Best practice for model translations?


#1

I’m working on a multilingual app in which the user can choose the content language (via a root route), e.g. an Article model might have a title string attribute which generates a slug for the URL and the title attribute should have translations for each supported language. Is there a best practice for designing translation in models? Does anyone have any experience with this? I’ve noticed several libraries that handle I18n well, but they are used for hardcoded translations only (unless I’ve missed something).

Thanks!


#2

In my app every translated object is just a different “document”. I have a attribute “translations” which is a hash with the locale string as key and as value an ID to a different document. Pretty easy to implement.


#3

Thanks @jgelens! By “document” you mean model? Do you have any example or mockup code? Does this kind of design complicate retrieving models by parameters that are translations?


#4

It’s easier than you think. For example the model:

CMS.Page = CMS.BaseModel.extend({
  title: DS.attr('string'),
  slug: DS.attr('string')
  translations: DS.attr(null, {defaultValue: {}}),
});

The returned data from the server will have something like this:

{
   "pages": [
      {
          "id": "45",
          "title": "Hello there",
          "slug": "hello-there",
          "translations": {
            "en": "45",
            "nl": "67"
        },
        {
          ...
        },
   ]
 }

This means the page with ID 45 has a translation with locale “nl” as ID 67. Just do a transition to the page with ID 67 when you clicking a button for example and you’re done.

The switch action in the controller:

switchLocale: function(locale) {
  var translatedPageId = this.get('translations')[locale];
  this.transitionToRoute('pages.edit', translatedPageId);
}, 

This is just one way to do it and it works great for my current use case, maybe also for you.


#5

Cool, this looks interesting and simple enough. When fetching Page records from the store, do you use a locale parameter, in case when e.g. you have a page with same slug for both languages? It seems like having a locale attribute in Page model might be useful in addition to translations - or is it redundant?


#6

I forgot to list it here, but the pages have indeed a locale attribute. Slugs are, in my case, always unique, so if you want slugs to be the same you’ll need a locale parameter in addition.

I’m just loading all pages in mem for overviews, but I filter them by the current selected locale.


#7

I should manage contends with locale, and I made a custom attribute (a transformation) that manage the translations.

My transform is that:

App.LocalizedStringTransform = DS.Transform.extend({
   serialize: function(value) {
       var ret={};
       value.forEach(function (e){
           ret[e.lang]= e.value;
       });
       return ret;
   },
   deserialize: function(value) {
       var ret=[];
       for (var language in value){
           ret.addObject(Ember.create({'lang':language, 'value':value[language]}))
       }
       return ret;
   }
});

After you should find the info with lang=your_language_key like:

this.get('data').find(function (e){
		return e.lang==idLanguage;
	}

I think is not the best efficient. But for me, ensures the translation from the server and to the server was correctly made.