Ext.define('MyApp.util.Translations',{ statics: { //list all translated languages available: ["EN", "DE"], data: { "login.label.notamember" : { "DE" : "Kein Mitglied?", "EN" : "Not a member?" }, "checkin.error.nickname" : { "DE" : "Der Spitzname muss zwischen {0} und {1} Zeichen lang sein.", "EN" : "Alias must be between {0} and {1} characters." }, //and so on ... } });Here comes the interesting part "Localization.js". Let me show you the code first and then I'll provide some explanation. Also ist is more or less self documenting.
Ext.define('MyApp.util.Localization', { //used as a shorthand alternateClassName: ['i10n'], requires: ['Ext.String','MyApp.util.Constants', 'MyApp.util.Translations', 'MyApp.util.Configuration'], singleton: true, config: { lang: null }, constructor: function() { //get browser/system locale this.setLang(this.getLanguage()); }, getTranslations: function() { return MyApp.util.Translations.data || {}; }, /** * @private * returns the browser language * e.g. DE, EN */ getLanguage: function() { var lang; //http://stackoverflow.com/questions/10642737/detecting-and-applying-current-system-language-on-html-5-app-on-android if (navigator && navigator.userAgent && (lang = navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { lang = lang[1]; } if (!lang && navigator) { if (navigator.language) { lang = navigator.language; } else if (navigator.browserLanguage) { lang = navigator.browserLanguage; } else if (navigator.systemLanguage) { lang = navigator.systemLanguage; } else if (navigator.userLanguage) { lang = navigator.userLanguage; } lang = lang.substr(0, 2); } lang = lang.toUpperCase(); console.log('browser language: '+lang); //check if this language is configured if(Ext.Array.indexOf(MyApp.util.Translations.available, lang) == -1) { console.log(lang + " not available using default " + appConfig.defaultLanguage); lang = appConfig.defaultLanguage; } else if(lang === 'undefined'|| lang.length == 0) { //use default language lang = appConfig.defaultLanguage; } //set language in configuration appConfig.language = lang; return lang; }, /** * Translates the given key into the corresponding value in selected language. * @param key * The key used to find a specific translation. * if the translated string contains placeholders in form of {0}, {1} ... eiter * 1. additional parameters with replacing values * OR * 2. an array containing placeholders * can be submited * @returns * Translation or key if none was found */ translate: function(key) { //alternativ with custom object and no sencha store var value = "", translations = this.getTranslations(); if (key && translations[key] && translations[key][this.getLang()] && translations[key][this.getLang()] !== '') { value = translations[key][this.getLang()]; if(arguments.length > 1) { //this is a string with placeholders //replace key with retrieved value and the call Ext.String.format var _array; if(Object.prototype.toString.call(arguments[1]) === '[object Array]') { _array = new Array(); _array[0] = value; for(var i = 0; i < arguments[1].length; i++) { _array[i+1] = arguments[1][i]; } } else { arguments[0] = value; _array = arguments; } //Documentation for Ext.String.format http://docs.sencha.com/touch/2-0/#!/api/Ext.String-method-format //we need apply because we don't know the number of arguments value = Ext.String.format.apply(this, _array); } } return (value == "") ? key : value; }, });We mark the class as a singleton and give it an alternate class name so we can easily call it from everywhere.
In the constructor we extract the system language and set in the lang config of our sencha app. If the system language is not translated we fall back to default language. To mark which languages have been translated simply add it to the available property in Translation.js.
The real "magic" ;) happen in translate.
Translate takes a key and looks it up in your Translation.js. If no translation is found simply the value of key is returned so you can easily see parts of your application which are not translated.
Your translation can contain placeholders in form of {0}, {1}. To supply the placeholders you can pass them either as an array or as normal arguments. I'll rely on a build in Ext Method for the formatting of the string.
And you're done.
Now translating something in your app is as simple as:
i10n.translate("checkin.error.nickname", 3, 25);
Keine Kommentare:
Kommentar veröffentlichen