Saturday, November 24, 2012

Using T4 for localizing JavaScript resources based on .resx files

In our project we're using two languages: Dutch and English. Furthermore, the IT company who built the application is using a framework on top of EXT.NET and thus there is a lot of JavaScript involved. There are a couple of solutions out there for localizing JavaScript in an ASP.NET MVC application, and I think the most common is this one:
<%$Resources:Resource, FieldName %>
But that his obvious limitations as described here Use ASP.NET Resource strings from within javascript files, namely you cannot use inside the body nor in .js files. I used a slightly different approach to localize the JavaScript in or project, based on the discussion here keeping three goals in mind:
  • Having only 1 place where resources are managed ( namely the .resx files )
  • Support for multiple cultures
  • Leverage IntelliSense - allow for code completion
Because of the last point - I decided to go with code generation. Code generation of course normally comes down to T4 Text Templates. So - currently we're using a text template in the /Scripts folder which generates Resources.js ( marked as 'copy to output directory' ) which is published on Web Deploy. Here's an example:
var Resources = {
  Common: {},
 };

Resources.Common.Greeting = { 
 'nl-NL': 'Hallo',
 'en-GB': 'Hi'
 };
Which gives me IntelliSense in JavaScript as it gives me in C#:
In the master page I'm including the JavaScript file and set the global space var 'locale' using the thread culture on the server:
   

This enables us to use the resources like this:
var msg = Resources.Common.Greeting[locale];
alert(msg);
And now for the T4 template:
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".js"#>
<#
 var path = Path.GetDirectoryName(Host.TemplateFile) + "/../App_GlobalResources/";
 var resourceNames = new string[1]
 {
  "Common"
 };

#>
/**
* Resources
* ---------
* This file is auto-generated by a tool
* 2012 Jochen van Wylick
**/
var Resources = {
 <# foreach (var name in resourceNames) { #>
 <#=name #>: {},
 <# } #>
};
<# foreach (var name in resourceNames) { 
 var nlFile = Host.ResolvePath(path + name + ".nl.resx" );
 var enFile = Host.ResolvePath(path + name + ".resx" );
 ResXResourceSet nlResxSet = new ResXResourceSet(nlFile);
 ResXResourceSet enResxSet = new ResXResourceSet(enFile);
#>

<# foreach (DictionaryEntry item in nlResxSet) { #>
Resources.<#=name#>.<#=item.Key.ToString()#> = { 
 'nl-NL': '<#= ("" + item.Value).Replace("\r\n", string.Empty).Replace("'","\\'")#>',
 'en-GB': '<#= ("" + enResxSet.GetString(item.Key.ToString())).Replace("\r\n", string.Empty).Replace("'","\\'")#>'
 };
<# } #>
<# } #>
Find the code snippet here The resourceNames array takes the names of the resource files that I want included in the .js file. The solution is generic enough for our needs right now, and if you would want to include other languages - some changes would be required. The shortcomings of this solution are of course that the size of the .js file might become quite large. However, since it's cached by the browser, we don't consider this a problem for our application. However - this caching can also result in the browser not finding the resource called from code.

28 comments:

  1. Dear Jochen,

    What a joy to find your well thought generic solution!

    I've integrated it in my project and I'm happily taking advantage of strings stored in both .resx (*.pt-BR and .resx) files. No more duplication. DRY principle.

    I'm going to share your post here: http://stackoverflow.com/q/104022/114029


    Thanks and God bless your life,


    Leniel

    ReplyDelete
    Replies
    1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru Dot Net Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
      or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

      Delete
  2. Thanks Leniel, glad you like it, thank you for the feedback.

    ReplyDelete
  3. Exactly what I needed! I came to the same conclusion as you, but the T4-part scared me. Fortunately, you have shown me the right path. Thank you.

    ReplyDelete
  4. Hello Jochen! If you are involved in l10n projects, I would suggest to evaluate a collaborative translation management platform like POEditor that can help you easily manage your projects.

    ReplyDelete
  5. Hi ,
    thanks for your great article , where can I find the code?!

    ReplyDelete
  6. I recently came across your blog and have been reading along. I thought I would leave my first comment.
    Java training in Chennai

    Java training in Bangalore

    ReplyDelete
  7. Thanks for sharing this amazing article. You are an awesome writer. Waiting for your future posts.
    IELTS Coaching in Chennai
    IELTS Training in Chennai

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. I have picked cheery a lot of useful clothes outdated of this amazing blog. I’d love to return greater than and over again. Thanks! 
    python Training institute in Pune
    python Training institute in Chennai
    python Training institute in Bangalore

    ReplyDelete
  10. Great thoughts you got there, believe I may possibly try just some of it throughout my daily life.
    Best Devops online Training
    Online DevOps Certification Course - Gangboard

    ReplyDelete
  11. I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.
    Data Science training in chennai
    Data Science training in OMR
    Data Science training in chennai
    Data Science Training in Chennai
    Data Science training in Chennai
    Data Science training in anna nagar
    Data science training in bangalore

    ReplyDelete

  12. This is quite educational arrange. It has famous breeding about what I rarity to vouch. Colossal proverb.
    This trumpet is a famous tone to nab to troths. Congratulations on a career well achieved. This arrange is synchronous s informative impolites festivity to pity. I appreciated what you ok extremely here 


    Selenium training in bangalore
    Selenium training in Chennai
    Selenium training in Bangalore
    Selenium training in Pune
    Selenium Online training

    ReplyDelete
  13. Thanks For sharing Your Information The Information shared Is Very Valuable Please Keep Updating Us Python Online Course Hadoop Online Course Data Science Online Course Aws Online Course

    ReplyDelete
  14. An amazing web journal I visit this blog, it's unbelievably wonderful. Oddly, in this blog's content made without a doubt and reasonable. The substance of data is informative.
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training

    ReplyDelete
  15. A bewildering web journal I visit this blog, it's unfathomably heavenly. Oddly, in this present blog's substance made purpose of actuality and reasonable. The substance of data is informative
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training

    ReplyDelete
  16. A bewildering web journal I visit this blog, it's unfathomably heavenly. Oddly, in this present blog's substance made purpose of actuality and reasonable. The substance of data is informative
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training

    ReplyDelete
  17. A befuddling web diary I visit this blog, it's incredibly grand. Strangely, in this present blog's substance made motivation behind fact and sensible. The substance of information is instructive
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training

    ReplyDelete
  18. An astounding web diary I visit this blog, it's inconceivably magnificent. Strangely, in this current blog's substance made point of fact and sensible. The substance of information is instructive.
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training

    ReplyDelete
  19. Attend The Python Training in Bangalore From ExcelR. Practical Python Training in Bangalore Sessions With Assured Placement Support From Experienced Faculty. ExcelR Offers The Python Training in Bangalore.

    ReplyDelete
  20. A befuddling web diary I visit this blog, it's incredibly grand. Strangely, in this present blog's substance made motivation behind fact and sensible. The substance of information is instructive
    Oracle Fusion Financials Online Training
    Oracle Fusion HCM Online Training
    Oracle Fusion SCM Online Training

    ReplyDelete
  21. Great blog created by you. I read your blog, its best and useful information.
    AWS Online Training
    Devops Online Training
    Apllication Packaging Online Training

    ReplyDelete
  22. Just now I read your blog, it is very helpful nd looking very nice and useful information.
    Digital Marketing Online Training
    Servicenow Online Training
    EDI Online Training

    ReplyDelete
  23. Thank you for excellent article.You made an article that is interesting.
    Tavera car for rent in chennai|Indica car for rent in chennai|innova car for rent in chennai|mini bus for rent in chennai|tempo traveller for rent in chennai
    Keep on the good work and write more article like this...

    Great work !!!!Congratulations for this blog


    ReplyDelete