When working with multilingual sites and apps, it is important to have a clean and systematic way to translate strings with dynamic content (like a number or date), e.g. “Showing results from {{date}}”.
Now, this functionality is built-in in frameworks like Rails. However, I recently wanted this functionality in javascript too. I ended up with this fairly simple approach.
Basically you define a translations variable, a hash. Since this is structured data, it could easily be generated from a back-end document or database (to keep all your translations in a single place). Here’s an example:
var translations = {
'results': {
'from_date': 'Showing results from {{date}}',
'header': 'Search results',
'...': '...'
},
'...': '...'
};
Then I wrote this simple function to handle the translations, inserting the dynamic values if present:
function translate(key, hash) {
string = eval('translations.'+key);
if (string && hash) {
var hash_keys = [];
for (i in hash) {
if (hash.hasOwnProperty(i)) {
hash_keys.push(i);
}
}
for (q in hash_keys) {
regex = new RegExp('\{\{'+hash_keys[q]+'\}\}','gi');
string = string.replace(regex, hash[hash_keys[q]].toString());
}
}
return string;
}
And now we can just do:
translate('results.from_date', {'date':new Date()});
Which will output “Showing results from Tue May 25 2010 17:19:06 GMT+0200 (CEST)”, where the last part is obviously the current date, inserted dynamically each time you call the translate function.
When you call the translate function, all you have to do is define the translation string you want to use and then optionally pass in a hash of dynamic values. Any part of the translation string that’s encapsulated in two curly-braces will be replaced with the value of the matching key from the dynamic values-hash.
So there we go, translations with dynamic value replacement in javascript.
It should be noted that this solution comes with a fairly strong assumption: the actual language change and setup is handled by the back-end. However, since you’ll likely want to handle language sessions, etc. in your back-end anyways, this hasn’t been much of an issue to us. You’ll likely want to generate the translations variable dynamically too (which was the reason it was defined as a low-level variable).