How to make i18n with Handlebars.js (mustache templates)?

35,909

Solution 1

I know this has been answered, but I'd like to share my simple solution. To build on Gazler's solution using I18n.js (which we use with our project at work), I just used a very simple Handlebars helper to facilitate the process to do the localization on the fly:

Handler

Handlebars.registerHelper('I18n',
  function(str){
    return (I18n != undefined ? I18n.t(str) : str);
  }
);

Template

<script id="my_template" type="x-handlebars-template">
    <div>{{I18n myVar}}</div>
</script>

The primary advantage of this is that there's no expensive pre/post processing on the entire json object. Not to mention if the incoming json has nested objects/arrays, the time spent looking for and parsing for them might get expensive if the object is huge.

Cheers!

Solution 2

https://github.com/fnando/i18n-js is a ruby gem that will create an internationalization file from your config/locales folder. However if you are not using rails, you can find the javascript used on its own here.

You then simply store the translations in a nested object..

I18n.translations = {"en":{"date":{"formats":{"default":"%Y-%m-%d","short":"%b %d","long":"%B %d, %Y"}}}};

Something that may also be of use to you that I use on my projects is a patch to mustache that automatically translates strings in the format @@translation_key@@

i18nize = function (result) {
    if (I18n) {
      var toBeTranslated = result.match(/@@([^@]*)@@/gm);
      if (!toBeTranslated) return result;
      for(var i = 0; i < toBeTranslated.length; i++) {
        result = result.replace(toBeTranslated[i], I18n.t(toBeTranslated[i].replace(/@/g, "")));
      }
    }
    return result;
};

You then call i18nize after render to allow you to put translations in your templates instead of passing them through.

Beware of patching mustache as you will not be able to port your templates to standard mustache implementations. However in my case, the benefits offered outweighed this issue.

Hope this helps.

Solution 3

Based on @poweratom 's answer :

Only with ember.js , same with options passed to I18n.js.

It will magically reload if computed properties are used.

Ember.Handlebars.helper "t", (str, options) ->
  if I18n? then I18n.t(str, options.hash) else str

Template:

{{t 'sharings.index.title' count=length}}

Yml:

en:
  sharings:
    index:
      title: To listen (%{count})

Solution 4

With NodeJs / Express :

  • node-i18n ( detect the Accept-Language header )

      app.use(i18n.init); 
    
  • Sample translation file

    {   
     "hello": "hello",   
     "home-page": {
       "home": "Home",
        "signup": "Sign Up"  
     } 
    }
    
  • In Express controller

    ...
    data.tr = req.__('home-page');
    var template = Handlebars.compile(source);
    var result = template(data);
    
  • Handlebars Template

        <li class="active"><a href="/">{{tr.home}}</a></li>
    

Solution 5

The question is answered but their may be a case where you do not want to depend on any i8n lib and use completely your own. I am using my own inspired from https://gist.github.com/tracend/3261055

Share:
35,909
pradon
Author by

pradon

Updated on July 09, 2022

Comments

  • pradon
    pradon almost 2 years

    I'm currently using Handlebars.js (associated with Backbone and jQuery) to make a web app almost totally client side rendered, and I'm having issues with the internationalisation of this app.

    How can I make this work?

    Are there any plugins?