Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multilingual in Meteor

I'm developing a multilingual app in Meteor.js I would like to know about best way in your opinion to do that; as example here is wat I'm doing right now (pretty sure that can be done better);

First I save items in mongodb with properties neted in a language root:

{
    en: {
      name: "english name",
      content: "english content"
    },
   it: {
      name: "italian name",
      content: "italian content"
    },
   //since images are the same for both, are not nested
   images: {
       mainImage: "dataURL",
       mainThumb: "dataURL"
   }
}

Then I publish a subscription using currentLang session variable:

Meteor.publish("elementsCurrentLang", function(currentLang) {

    var projection = {
        images: 1
    };

    projection[currentLang] = 1;

    return Elements.find({}, projection);
});

I subscribe on route using Iron Router waitOn hook:

Router.route('/eng/elements', {
    waitOn: function() {
        return Meteor.subscribe("municipalitiesCurrentLang", Session.get('currentLang'));
    },
    action: function() {
        this.layout('ApplicationLayout');
        this.render('elements');
    } 
});

Now the first problem: I would like to reuse the same template for every language, but I can't simply put in the template {{name}} or {{content}} since the subscription returns the attributes nested under lang root, so it is needed to do for example {{en.name}} for english or {{it.name}} for italian; To avoid this I use a template helper that buids a new object; essentially it removes attributes from the lang root:

Template.elements.helpers({
    elements: function() {
        var elements = Elements.find();
        var currentLang = Session.get('currentLang');
        var resultList = [];

        elements.forEach(function(element, index) {
            var element = {
                name: element[currentLang].name,
                content: element[currentLang].nameUrl,
                images: element.images
            };

            resultList.push(element);
        });

        return resultList;
    }
});

And now in the template I can access attributes like wanted:

 <h1>{{name}}</h1>
 <p>{{content}}</p>

Before continuing with this approach I want to listen for suggestions, since I don't know if this will work well; when Session.currentLang will change, the subscription will be reloaded? is there a way to avoid the forEach loop in template helpers?

like image 699
Cereal Killer Avatar asked Dec 05 '14 19:12

Cereal Killer


1 Answers

I'm developping a multilangage web app too and I advise you to use a package, like this one : https://atmospherejs.com/tap/i18n

You can change the langage reactively. Have the same template for all your langages, as you want ! You can put it as a parameter in the route. Personnaly I use it as a Session variable and in the user profile !

If you use this package, you also can export your app, or part of it, more easily as many developpers will use the same code.

you put all your words in json files :

en.i18n.json:
{
    "hello": "hello"
}
fr.i18n.json:
{
    "hello": "bonjour"
}

and

{{_ "hello" }}

will write hello or bonjour depending of the langage set. You can set it with :

TAPi18n.setLanguage(getUserLanguage())
//getUserLanguage() <- my function to get the current langage in the user profile or 
the one used by the navigator
like image 165
roro_57 Avatar answered Sep 19 '22 13:09

roro_57