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; }
2 commentaires:
Salut,
ne fonctionne pas avec par exemple :
"vous êtes {0} et vous avez {1} ans"
Merci metropical pour cette remarque. En effet, le fait d'avoir plusieurs patterns dans un même clé posait pb.
La fonction _format est uniquement appelée depuis la fonction translate où le 2ième argument envoyé en paramètre de _format est déjà transformé en Array.
Une seconde transformation dans _format est donc inutile et source d'erreur.
Enregistrer un commentaire