Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where do I put the translations for Ember-I18n in Ember-CLI?

I am new to ember, and ember-cli and I'm still learning where everything goes. I'm trying to add multilingual support with the ember-i18n module.

I have the dependencies installed with bower

bower install cldr ember-i18n --save

And I've got my imports working in Brocfile.js

app.import('vendor/cldr/plurals.js');
app.import('vendor/ember-i18n/lib/i18n.js');

In my app the i18n handlebar helper is working

{{t hello}} gives me "Missing translation: hello"

I don't know where to put or reference a file in the ember-cli folder structure that contains the translations.

Per ember-i18n documentaton it would look something like this

Ember.I18n.translations = {
    hello: "Hello World",
}

I tried sticking it in app.js just to see it working but got the error:

Uncaught TypeError: Cannot set property 'translations' of undefined
like image 554
Weston Avatar asked Jun 21 '14 18:06

Weston


3 Answers

You can add your translations within an initializer (docs here). With ember-cli you can generate one by doing ember generate initializer i18n on the command line.

Within the initializer you can set the translations:

var TRANSLATIONS = {
  'user.edit.title': 'Edit User',
  'user.followers.title.one': 'One Follower',
  'user.followers.title.other': 'All {{count}} Followers',
  'button.add_user.title': 'Add a user',
  'button.add_user.text': 'Add',
  'button.add_user.disabled': 'Saving...'
};
var i18nInitializer = {
  name: 'i18n',
  initialize: function() {
    Ember.I18n.translations = TRANSLATIONS;
  }
};
export default i18nInitializer;

If you want to retrieve the language data via ajax in a java-properties file you can retrieve it with ajax and parse it with java-properties.js. It is also available via Bower

like image 56
Willem de Wit Avatar answered Oct 20 '22 06:10

Willem de Wit


I had the same issues as Weston and after some research I've implemented a solution to this that can dynamically load a language specified by the user. This is probably too late for the OP, but I'm putting it here for future reference for anyone else that may have questions about this process.

My solution may not be the ideal way to handle doing this but it seems to work nicely with my site.

I'm using Ember-cli and included ember-i18n, for internationalization, as well as CLDR to handle plurals. My site uses a cookie to store the user language, which is used to load the appropriate language file when the site loads. The cookie is also passed along to the REST service (some API calls return objects that could contain translated text). I'm using jQuery-cookie for my cookie handling.


First I created my translations files, one for each language, which are just javascript files that I will then load in using $.getScript. I stored them in a 'translations' folder within the public/javascript folder Ember-cli created.

translations-en.js

Ember.I18n.translations = {
  'hello' : 'Hello World!',
  ...
}

translations-fr.js

Ember.I18n.translations = {
  'hello' : 'Bonjour Monde!',
  ...
}

Then I set the initializer for CLDR, which sets the default language based on the user-lang cookie my site uses - if the cookie doesn't yet exist it defaults to 'en' and creates the cookie.

\app\initializers\cldr.js

export default {
  name: 'cldr',

  initialize: function() {
    var lang = $.cookie('user-lang');

    if (lang === undefined) {  // no cookie exists yet
      lang = 'en';
      $.cookie('user-lang', lang, {expires:365, path:'/'});
    }

    CLDR.defaultLanguage = lang; 
  }
};

Now in the Application Route's beforeModel function I grab the translations file based on the value stored in CLDR.defaultLanguage.

\app\routes\application.js

export default Ember.Route.extend({

  beforeModel: function() {
    $.getScript('./javascript/translations/translations-' + CLDR.defaultLanguage + '.js')
      .fail(function(jqxhr, reason, exception) {
        // handle failure
      });
  }
});

If your site has a large number of translation strings, or many languages, you may not want to have your translation files included every time someone loads your app or it could take a while to load. In that case you can replace this getScript with an ajax call and get the file served up by your backend. In my case there are not too many translation strings so this is ok.

Now any time a user wants to change the language all I have to do is update the value of my user-lang cookie and then reload the site, which will go through the initializer and beforeModel functions again and load the appropriate language file.

export default Ember.Controller.extend({
  actions: {
    changeLanguage: function(lang) {
      $.cookie('user-lang', lang); 

      window.location.reload();
    }
  }
});

Any time the user reloads the page or returns to the site their last selected language will be loaded from the cookie by default. Of course, the user could delete their cookie or log in from a different browser, in which case the site will return to the default 'en' language. To get around this the user's language selection would need to persist somewhere on the back-end and be fetched on app load - but that's another task.

like image 41
SeanK Avatar answered Oct 20 '22 06:10

SeanK


The namespace is wrong.

You need Em.I18n.translations.

Tried it. Works.

I don't know where to put or reference a file in the ember-cli folder structure that contains the translations.

Me neither. Of course app.js works but maybe someone can provide a nice hint. I'm pretty new to all that ember-cli stuff as well...

like image 41
Doe Johnson Avatar answered Oct 20 '22 07:10

Doe Johnson