Created
February 21, 2012 17:58
-
-
Save peburrows/1877814 to your computer and use it in GitHub Desktop.
javascript localization library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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?" | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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(); | |
| }()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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?", | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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