Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MVC JavaScript localization of external .js files

0.00/5 (No votes)
13 May 2012 1  
A system that permit you to manage your external javascript files and use server localizations in it.

I Googled some days for a solution for tranlating JavaScript string placed in external files without finding any simple solution. I found many solutions that store resource in separate files or store translated strings in dictionaly. This solutions was not perfect in my scenario becouse store all translated strings in client browser also when the usere require only a language.

Another reason is that in all this solution you need to reference a translated string by reference a special variable like (progect.translation.testMessage['it-IT']).

I think that the user need only his language strings on the client js file and I prefere to use a string like this @Cult.Text("ID") in the JavaScript code.

First Statement: Why not use the MVC Razor view engine to render the javascript external file script ?

I create a JsController.cs:

 public class JsController : Controller
{
 // Remember to manage the cache here
 public JavaScriptResult Index(string js, string lang, string ver)
 {
  Response.ContentType = "text/javascript";


  var script = RenderRazorViewToString(js, null);
  var jsRet = new JavaScriptResult();


  script = script
   .Replace("<script type=\"text/javascript\">", string.Empty)
   .Replace("<script>", string.Empty)
   .Replace("</script>", string.Empty);


  var javaScriptMinifier = MinifierFactory.Get<JavaScriptBundle, JsMinMinifier>();


  string minifiedJavaScript = javaScriptMinifier.Minify(script);


  jsRet.Script = minifiedJavaScript;
  return jsRet;
 }


 private string RenderRazorViewToString(string viewName, object model)
 {
  ViewData.Model = model;


  using (var sw = new StringWriter())
  {
   var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
   var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
   viewResult.View.Render(viewContext, sw);
   viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
   return sw.GetStringBuilder().ToString();
  }


 }

}

Then in the Views folder I create a test.js.cshtml view. In this view you can generate your javascript libraries using all power of razor engine (Why not??) You can also create a separate file for a different library and you can use intellisense by adding <script></script> tags tha are removed when rendering the view.

The view is also minified with Squishit

   @{
        Layout = "";
    }    


    <script type="text/javascript"> // Use this line to get Intellisense...
        function Test() {
            alert("@Cult.Text("TEST")");
            return false;
        };
    </script>

 In _Layout.cshtml I refer to the script (calling the controller) passing it the current language and version only to manage the cached client file.

You need to manage the cache by creating a Helper to generate the controller path (Use reflection to generate the version of the assemply):

<script src="<a>/Js?js=test.js&lang=@Cult.CurrentCulture()&ver=1.4</a>" Type="text/javascript"></script>

I use this great solution to store the current user culture into a cookie and get it server side: Is it safe to use an HttpModule for localization?

I create a Cut class the manage the translation system, this is a simple implementation you can use resource or other system to translate your strings:

public static class Cult
{
 public static string CurrentCulture()
 {
  return System.Threading.Thread.CurrentThread.CurrentCulture.Name.Substring(0, 2).ToLower();
 }


 public static string Text(string messageID)
 {
  // This is a fake translation repository implementation but you can use a DB o resource...
  var currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name.Substring(0, 2).ToLower();


  var defaultMessage = string.Empty;


  if (messageID == "TEST")
   return currentCulture == "it" ? "Testo di prova in Italiano" : "Text message in English";


  return currentCulture == "it" ? "Clicca qui per effettuare il test di localizzazione" : "Click here to test the localization";;
 }


}


That's it!! I create a system that permit you to manage your external javascript files and use localizations on it.

The sample is in the attachment file... plese update all referenced packages with NuGet.

The comments are much appreciated.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here