Question

I've finally gotten my PhoneGap / Backbone / Handlebars to localize using i18next.js -- kind of.

I'm currently wondering how to get html with embedded handlebars expressions to both localize and compile with Handlebars. As an example, I want something like this:

Welcome, {{this.name}}. We've been expecting you.

to turn into:

Welcome, Bob. We've been expecting you.

That's easy enough without localization. But run through the i18next template described in the docs (here: http://i18next.com/pages/doc_templates.html)...

// handlebars helper from i18next
Handlebars.registerHelper('t', function(i18n_key) {
  var result = i18n.t(i18n_key);
  return new Handlebars.SafeString(result);
});

//Handlebars string:
{{t 'view.WelcomeMessage'}}

// translation.json file
{ "view":
    {
        "WelcomeMessage": "Welcome, {{this.name}}. We've been expecting you."
    }
}

Unfortunately, this turns into the following when localized:

Welcome, {{this.name}}. We've been expecting you.

How do I get the string to localize and have embedded expression compile?

Was it helpful?

Solution

It looks like the the answer for this is in the variable replacement helper tr:

// handlebars helper from i18next
Handlebars.registerHelper('tr', function(context, options) { 
  var opts = i18n.functions.extend(options.hash, context);
  if (options.fn) opts.defaultValue = options.fn(context);
  var result = i18n.t(opts.key, opts);
  return new Handlebars.SafeString(result);
});

// random "This" object passed in:
var person = {name:"Bob", age:42, eyeColor:"blue"};

//Handlebars string:
{{tr this key='view.WelcomeMessage'}}

// translation.json file
{ "view":
  {
    "WelcomeMessage": "Welcome, __name__. We've been expecting you."
  }
}

// Output
Welcome, Bob. We've been expecting you.

Note that the tr example given on http://i18next.com/pages/doc_templates.html does have an extra parameter at the end. This is only necessary if you want to replace one of the this attributes with something else.

OTHER TIPS

For i18next v3.2.0, which has interpolation:

package.json | dependencies/dev dependencies

"i18next": "^3.1.0",
"babel-core": "^6.7.2",
"babel-loader": "^6.2.4",
"handlebars": "^4.0.2",
"handlebars-loader": "^1.1.4",
"webpack": "^1.12.2",

layoutView.js | example of the model data being passed to the template:

  render(){
    let person = {name: 'joe', age: 21};
        person = new Backbone.Model(person);
    this.$el.html(template(person.toJSON()));
  }

layoutView.hbs | handlebars template

<div>{{{ i18n 'person' name=this.name age=this.age}}}</div>
<!-- after interpolation will read -->
<!-- <div>joe is 21 lang: en </div> -->

i18n.js | using es2015 so file name becomes the helperName used in layoutView.hbs (above)

// handlebars helper from i18next
import i18next from 'i18next';
import Handlebars from 'handlebars';

export default function(key, options) {
 let result = i18next.t(key, options.hash);
 return new Handlebars.SafeString(result);
};

translation.json | sample for interpolation

{
  "person": "{{name}} is {{age}} lang: en",
  "good-bye": "good-bye: en",
  "other": "other: en"
}

This thread on github really helped

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top