7

How is i18n handled within Sencha touch? (I am talking of localization support for strings, but also of localized components)

A more specific question: I have a form that contains a date picker, how do I make sure that the date will be displayed and picked in european format when I access the application using a french android phone?

Cheers

Rom1
  • 3,167
  • 2
  • 22
  • 39

5 Answers5

8

There isn't an official API for i18n in SenchaTouch, yet. Although in Ext 4 there are localization files for all components in the /locale folder.

There is an old tutorial that indicates a way, by dynamically in setting the src attribute of a script tag according to the locale.

<script type="text/javascript" id="extlocale"></script>
<script type="text/javascript">

var browserLang = window.navigator.language; // get the browsers language
var locales = [ 'fr', 'es', 'pt', 'pt-BR', 'pt-PT' ]; // available locale files
var locale = 'fr'; // default locale

// check browser language against available locale files
for (var i = locales.length - 1; i >= 0; i--) {
    if (browserLang === locales[i]) {
        locale = browserLang;
        break;
    }
};

// Insert src attribute to extlocale
if(locale) {
    Ext.fly('extlocale').set({src:'ext/locale/ext-lang-' + locale + '.js'});
}

</script>

Use window.navigator.language to check the browser's language.

Locale files must be set in /ext/locale/ext-lang-fr.js
Where you can override the components properties.

Ext.onReady(function() {

if(Date){
    Date.shortMonthNames = [
        "Janv",
        "Févr",
        "Mars",
        "Avr",
        "Mai",
        "Juin",
        "Juil",
        "Août",
        "Sept",
        "Oct",
        "Nov",
        "Déc"
    ];

    Date.getShortMonthName = function(month) {
        return Date.shortMonthNames[month];
    };

    Date.monthNames = [
        "Janvier",
        "Février",
        "Mars",
        "Avril",
        "Mai",
        "Juin",
        "Juillet",
        "Août",
        "Septembre",
        "Octobre",
        "Novembre",
        "Décembre"
    ];

    Date.monthNumbers = {
        "Janvier" : 0,
        "Février" : 1,
        "Mars" : 2,
        "Avril" : 3,
        "Mai" : 4,
        "Juin" : 5,
        "Juillet" : 6,
        "Août" : 7,
        "Septembre" : 8,
        "Octobre" : 9,
        "Novembre" : 10,
        "Décembre" : 11
    };

    Date.getMonthNumber = function(name) {
        return Date.monthNumbers[Ext.util.Format.capitalize(name)];
    };

    Date.dayNames = [
        "Dimanche",
        "Lundi",
        "Mardi",
        "Mercredi",
        "Jeudi",
        "Vendredi",
        "Samedi"
    ];

    Date.getShortDayName = function(day) {
        return Date.dayNames[day].substring(0, 3);
    };

    Date.parseCodes.S.s = "(?:er)";

    Ext.override(Date, {
        getSuffix : function() {
            return (this.getDate() == 1) ? "er" : "";
        }
    });
}

});

I made a working prototype you can check out here:
http://lab.herkulano.com/sencha-touch/date-picker-i18n/

herkulano
  • 548
  • 3
  • 10
  • Ext.fly('extlocale').set({src:'ext/locale/ext-lang-' + locale + '.js'}); does not seem to work for me. Can you help me with this? – Khush Mar 20 '12 at 07:51
2

For your own strings (not talking about native touch component) you could do something like this.

1) In your index.html in the head section, load a LocaleManager.js file (whatever the name) before the

<script id="microloader" type="text/javascript" src="sdk/microloader/development.js"></script>

In your localeManager, depending on your browser's language load the resource file corresponding to your language (myStrings-fr.js | myStrings-en.js )

You can do something like this to get the language in the browser:

window.navigator.language || window.navigator.userLanguage || window.navigator.browserLanguage || window.navigator.systemLanguage

2) Create your resources files with your translated string

It should look like this for the english version (myStrings-en.js) :

var myStrings = {
MyPackage1: {
    myString1: 'Seach...'
}};

It should look like this for the french version (myStrings-fr.js) for example :

var myStrings = {
MyPackage1: {
    myString1: 'Recherchez...'
}};

3) In your sencha touch code, for example for a searchfield place holder value

xtype: 'searchfield',
id: 'searchToolbarItem',
placeHolder: myStrings.MyPackage1.myString1

Hope it will help.

Another solution could be to modify the build process of your sencha touch app and create localized versions of your app when building it. So there would be one version per language. Then depending on the brower language you would load the right version of your app when loading the app in the browser.

Ronan Quillevere
  • 3,699
  • 1
  • 29
  • 44
  • Hi Ronan, this is what i have been looking for. Please do you have an implementation of LocaleManager.js ? Thanks. LISA – Lisa Anne Jul 09 '14 at 06:14
  • Sorry I cannot give you the code. You just need to use JQuery to add a new Script element to your page with the myStrings-XX.js as the src. – Ronan Quillevere Jul 09 '14 at 12:39
0

I wrote my own i18n class, here it is:

Ext.define('MyApp.util.I18n', {
    singleton : true,

    config : {
        defaultLanguage : 'en',
        translations : {
            'en' : {
                'signIn' : 'Sign in',
                'name' : 'Name',
                'hello' : 'Hello {0} !',
                        'enOnly' : 'English only !'
            'fr' : {
                'signIn' : 'Identifiez-vous',
                        'name' : 'Nom',
                        'hello' : 'Bonjour {0} !'
            }
        }
    },

    constructor: function(config) {
        this.initConfig(config);
        this.callParent([config]);
    },

    translate: function (key) {

        // Get browser language
        var browserLanguage = window.navigator.userLanguage || window.navigator.language;

        // Is it defined ? if not : use default
        var language = this.getTranslations()[browserLanguage] === undefined ? this.getDefaultLanguage() : browserLanguage;

        // Translate
        var translation = "[" + key + "]";
        if (this.getTranslations()[language][key] === undefined) {

            // Key not found in language : tries default one
            if (this.getTranslations()[this.getDefaultLanguage()][key] !== undefined) {
                translation = this.getTranslations()[this.getDefaultLanguage()][key];
            }

        } else {

            // Key found
            translation = this.getTranslations()[language][key];
        }

        // If there is more than one argument : format string
        if (arguments.length > 1) {

            var tokenCount = arguments.length - 2;
            for( var token = 0; token <= tokenCount; token++ )
            {
                translation = translation.replace( new RegExp( "\\{" + token + "\\}", "gi" ), arguments[ token + 1 ] );
            }

        }

        return translation;

    }
});

Then you can call it like this:

MyApp.util.I18n.translate('signIn'); 
// Gives 'Identifiez-vous'

MyApp.util.I18n.translate('hello', 'Gilles'); 
// Gives 'Bonjour Gilles !'

MyApp.util.I18n.translate('enOnly'); 
// Gives 'English only !' (defaults to en, as the key is not defined for fr)

MyApp.util.I18n.translate('missing'); 
// Gives '[missing]' (the key is never defined, so it is returned into brackets)

For more information, you can read the original blog post here: http://zippy1978.tumblr.com/post/36131938659/internationalization-i18n-with-sencha-touch

zippy1978
  • 632
  • 5
  • 3
0

Here is my implementation:

enter image description here

I want me app to be translated to English and Spanish, based in the device's language, if the language is not Spanish, then it takes the default (English). Here are my classes:

Ext.define('MyApp.i18n.I18N', {
    alternateClassName: 'i18n',
    singleton: true,
    constructor: function(config) {
        var lang = window.navigator.userLanguage || window.navigator.language

        if(lang==='undefined' || lang.substring(0,2) != 'es'){ //don't care about region
            lang = 'defaultLocale';
        }

        return Ext.create('MyApp.i18n.locales.' + lang, config);
    }
});


Ext.define('MyApp.i18n.locales.defaultLocale', {
    hello:'Hello'
});

Ext.define('MyApp.i18n.locales.es', {
    extend: 'MyApp.i18n.locales.defaultLocale',
      hello:'Hola'
});

And here is how you call it:

i18n.hello

I hope it helps.

Roberto Rodriguez
  • 3,179
  • 32
  • 31
-1

locale folder is under /src folder in sencha touch

Dawesi
  • 568
  • 3
  • 9