Skip to content

Instantly share code, notes, and snippets.

@peburrows
Created February 21, 2012 17:58
Show Gist options
  • Save peburrows/1877814 to your computer and use it in GitHub Desktop.
Save peburrows/1877814 to your computer and use it in GitHub Desktop.
javascript localization library
// English translations
{
"en" : {
"error" : {
"fetching" : "An error occurred while attempting to fetch %{what}",
"notified" : "We've been notified about this issue, and we'll take a look at it shortly."
},
"confirm" : {
"delete" : "Are you sure you want to delete this highlight?"
}
}
}
var i18n = (function(){
// this copy of the i18n object is for the constructor
var i18n = function(){
// privleged vars
var _locales = {};
// public vars
this.locale = 'en';
// priviledged methods that can access local variables;
this.locales = function(){ return _locales; };
this.localeList = function(){
var ll = [];
for(var l in _locales){ ll.push(l); }
return ll;
};
this.addLocale = function(){
// make sure the second argument isn't a callback
if((arguments.length >= 2) && (arguments[1].constructor == Object)){
_locales[arguments[0]] = arguments[1];
// make sure there's a callback and that the callback is a function
if(arguments[2] && (arguments[2].constructor == Function)){
return arguments[2](arguments[1]);
}
}else{
var path = arguments[0],
pathParts = path.split('/'),
locale = pathParts[pathParts.length - 1].split('.')[0],
self = this,
callback = arguments[1];
// this timestamp is because android can cache this junk w/o telling us
// we probably need a more robust way that doesn't include ALWAYS pull a new copy
var timestamp = new Date().getTime();
if(path.indexOf('?') < 0){ path += '?' + timestamp; }
else{ path += '&' + timestamp; }
$.getJSON(path, function(data){
self.addLocale(locale, data[locale], callback);
});
}
};
};
// public methods
// really no good reason to put these on the prototype object instead of just declaring them in the constructor, but...
// I feel like putting them here right now.
//
// for the translate method, I'm still trying to decide if it's worth
// having the option to raise an error if the translation or locale can't be found
i18n.prototype.translate = function(key){
var thisLocale = this.locales()[this.locale];
var replacements = arguments[1] || {},
tokenizer = /(%%\{[^\}]+\}|%\{[^\}]+\})/,
interpolation = /(%)?(%\{([^\}]+)\})/,
tokens;
// get out of here if we can't find the locale
if(!thisLocale){ return 'locale not found: ' + this.locale; }
var parts = key.split('.'),
found = thisLocale;
for (var i=0; i < parts.length; i++) {
found = found[parts[i]];
if(!found){ return 'translation not found: ' + key; }
};
// we only handle strings
if(found.constructor != String){ return 'translation not found: ' + key; }
// now that we've found it, begin interpolation...
tokens = found.split(tokenizer);
var t;
for (var i = tokens.length - 1; i >= 0; i--){
if( t = tokens[i].match(interpolation) ){
// need to see if the last element of the tokens array matches any of the replacements
// that were passed in and change the value in the tokens array if it does
if(replacements && replacements[t[t.length-1]]){
tokens[i] = replacements[t[t.length-1]];
}
}
};
return tokens.join('');
};
// alias the translate function
i18n.prototype.t = i18n.prototype.translate;
return new i18n();
}());
// Portugues translations
{
"pt" : {
"error" : {
"fetching" : "Ocorreu um erro ao tentar capturar %{what}",
"notified" : "Sabemos da ocorrncia deste problema e o resolveremos em breve.",
},
"confirm" : {
"delete" : "Tem certeza de que deseja excluir este?",
}
}
}
// USAGE
// English
i18n.addLocale('/javascripts/locales/en.js');
// Portuguese
i18n.addLocale('/javascripts/locales/pt.js');
// set the current locale
i18n.locale = 'en';
// translate a string:
i18n.t('confirm.delete') //=> "Are you sure you want to delete this?"
// translate a string with a dynamic value
i18n.t('error.fetching', {what: 'stuff'}) //=> An error occurred while attempting to fetch stuff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment