Difficile de gérer le multilinguisme (i18n) en Javascript ! Et pourtant, on est souvent tenté de rapidement écrire dans son code des messages destinés à l'utilisateur. La gestion a posteriori de plusieurs langues devient alors un casse tête. Mieux vaut anticipé et externaliser ses libellés.
- var labels_fr = {
- 'hello' : 'Bonjour {0}, tu as {1} ans',
- 'quit' : 'Quitter ?'
- }
- var labels_en = {
- 'hello' : 'Hello {0}, you are {1}',
- 'quit' : 'Quit ?'
- }
La classe ci-dessous permet d'obtenir simplement le libellé souhaité en fonction de la langue :
- var i18n = new I18n();
- i18n.load(labels_fr);
- i18n.translate('hello','JC', '33');
Plus propre, non ?
La classe en question (UPDATE 18/10/2010 : prise en compte de plusieurs patterns) :
- /**
- * I18n est une classe permettant d'obtenir un libellé
- * caractérisé par une clé dans une map contenant un
- * ensemble de libellés traduits dans la langue choisie
- * @constructor
- */
- var I18n = function(){}
- /**
- * Charge la map de clés/libellés
- * @param {Object} translations Les clés/libellés traduits
- * @constructor
- */
- I18n.prototype.load = function(translations) {
- this._translations = translations;
- }
- /**
- * Remplace les nombres entre accolades ({0}) par les
- * chaînes de caractères passées en paramètre
- * exemple : _format('Hello {0} ! ', 'guy') => Hello guy !
- * @param {String} format La chaîne de caractère à formater
- */
- I18n.prototype._format = function(format) {
- var args = arguments[1];
- return format.replace(/\{(\d+)\}/g, function(m, i){
- return args[i];
- });
- }
- /**
- * Retrouve le libellé correspondant à la clé passée en paramètre
- * et le formate en fonction des paramètres supplémentaires
- * exemple : translate('hello', 'guy') => Hello guy !
- * @param {String} key La clé à traduire
- */
- I18n.prototype.translate = function(key) {
- if (typeof(this._translations)!='undefined' && this._translations[key]) {
- return this._format(this._translations[key],Array.prototype.slice.call(arguments,1));
- }
- return key;
- }