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?
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.
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.
This is the solution I ended up doing. It worked out quite nicely, and I also learnt about using $.Deferred which was great!
The key for me was using the require text plugin as a loader in the code.
The default locale is set as a dependency, that way it's baked in the build as well.
Explanations are in the code below: