Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load Locale File Dynamically using Requirejs

I have a single page Marionette app built on RequireJS which needs to support translations.

My goal is to have a dictionary file for each language, and based on the logged in user's configuration, load the relevant file.

Since most of the users will use English, I want to bundle the English dictionary in the app during build (using r.js).

I wrote a small Translator module, which basically wraps jed.js (the library I'm using for i18n):

//in myTranslator.js
define(function (require) {
    "use strict";

    var Jed = require("jed");
    var localeData = require("json!locales/en_US.json");

    var Translator = function () {
        var i18n = new Jed({
            "domain": "messages",
            "locale_data": localeData
        });
        return i18n;
    };
    return Translator;
});

//in app.js
define(function(require){
    var Translator = require("myTranslator");
    var translator = new Translator();
});

As you can see, the locale data is loaded from a static file. I want to be able to pass in the locale to the Translator constructor, and based on that, load the correct JSON file.

How can that be done together with keeping the English JSON bundled with the built project?

like image 320
elanh Avatar asked Oct 27 '13 18:10

elanh


1 Answers

You should be able to check user settings, construct a dependency string, pass it to Translator and then use it instead of localeData — r.js will ignore the dynamic dependency but should bundle EN locale.

if ( userLocale && userLocale !== 'en_US' ) {

    var localePath = 'json!locales/' + userLocale + '.json';
    require([ localePath ], function( locale ) {
        var translator = new Translator( locale );
    });

}

and inside Translator: "locale_data": passedData || englishData.

(or do the same inside the Translator module, like if ( userLocale !== 'en_US' ) { require([path], function(locale) {...}))

In theory it should work, though you cannot use simplified CommonJS here and should use callback-require, otherwise you'll get Module name ... has not been loaded yet for context error.

like image 161
Stefan Avatar answered Sep 18 '22 13:09

Stefan