#459 separe i18n code from Recline

This commit is contained in:
krzysztofmadejski
2016-11-14 12:49:34 +00:00
parent e9f6554eac
commit 55c51cfad6
3 changed files with 146 additions and 101 deletions

View File

@@ -1,36 +1,54 @@
/*jshint multistr:true */
// TODO probably some kind of mixin would be better, like: my.View - Backbone.View.extend({}); _.extend(my.View, Backbone.I18nView);
"use strict";
var I18nMessages = function(uniqueID, translations, languageResolverOrLocale, appHardcodedLocale) {
var defaultResolver = function() {
};
Backbone.I18nView = Backbone.View.extend({
defaultLocale: 'en',
locale: 'en',
cache: {},
initializeI18n: function(locale, appHardcodedLocale) {
this.defaultLocale = appHardcodedLocale || 'en';
this.locale = locale || this.defaultLocale;
// which locale should we use?
languageResolverOrLocale = (typeof languageResolverOrLocale !== 'undefined') ? languageResolverOrLocale : defaultResolver;
appHardcodedLocale = appHardcodedLocale || 'en';
this.cache[this.locale] = {};
},
if (typeof(languageResolverOrLocale) === 'function') {
languageResolverOrLocale = languageResolverOrLocale();
}
if (languageResolverOrLocale == undefined) {
languageResolverOrLocale = appHardcodedLocale;
}
if (I18nMessages.prototype._formatters[uniqueID, languageResolverOrLocale]) {
return I18nMessages.prototype._formatters[uniqueID, languageResolverOrLocale];
}
I18nMessages.prototype._formatters[uniqueID, languageResolverOrLocale] = this;
// ========== VARIABLES & FUNCTIONS ==========
var self = this;
this.locale = languageResolverOrLocale;
this.cache= {};
this.getLocale = function() {
return this.locale;
};
// ============= FormatJS.io backend =========
this.t = function(key, values, defaultMessage) {
values = (typeof values !== 'undefined') ? values : {};
// TODO how to use it from outside? an singleton instance of I18n? use case: pass translated strings into view initializer
t: function(key) {
this.t(key, {}, null);
},
t: function(key, values, defaultMessage) {
// get the message from current locale
var msg = recline.View.translations[this.locale][key];
var msg = this.translations[this.locale][key];
// fallback to key or default message if no translation is defined
if (msg == null) {
if (this.locale != this.defaultLocale) {
if (this.locale != this.appHardcodedLocale) {
console.warn("Missing locale for " + this.locale + "." + key);
}
msg = defaultMessage;
}
if (msg == null) {
msg = key;
if (this.locale === this.defaultLocale) {
if (this.locale === this.appHardcodedLocale) {
// no need to define lang entry for short sentences, just use underscores as spaces
msg = msg.replace(/_/g, ' ');
}
@@ -38,9 +56,9 @@ Backbone.I18nView = Backbone.View.extend({
}
try {
var formatter = this.cache[this.locale][msg];
var formatter = this.cache[msg];
if (formatter === undefined) {
this.cache[this.locale][msg] = formatter = new IntlMessageFormat(msg, this.locale);
this.cache[msg] = formatter = new IntlMessageFormat(msg, this.locale);
}
var formatted = formatter.format(values);
@@ -56,16 +74,18 @@ Backbone.I18nView = Backbone.View.extend({
}
},
MustacheFormatter: function() {
var formatter = new Proxy(this, {
get: function(view, name) {
// ============ Mustache integration ========
this.mustacheI18Tags = function() {
var tagsProxy = new Proxy(this, {
get: function(messages, name) {
return function() {
var f = function (text, render) {
var trans = view.t(name, this, text);
var trans = messages.t(name, this, text);
return render(trans);
}
f.toString = function() {
return view.t(name);
return messages.t(name);
}
return f;
};
@@ -76,7 +96,11 @@ Backbone.I18nView = Backbone.View.extend({
});
return {
't': formatter,
't': tagsProxy,
};
},
});
this.injectMustache = function(tmplData) {
return _.extend(tmplData, self.mustacheI18Tags());
}
};