JavaScript Internationalisation
9 Comments
Comments are ordered by helpfulness, as indicated by you. Help us pick out the gems and discourage asshattery by voting on notable comments.
Got something to add? You can leave a comment below.
Matthew
Ed Eliot
An interesting read, however wherever possible I’d suggest trying to generate your look up object (i18n) server side which allows you to take advantage of existing localisation mechanisms. By doing this you could avoid having to write much of the code described above. Generally I’d include the look up object in the HTML head (assuming few translations) or in a separate dynamically generated file (with suitable HTTP headers set to ensure caching).
Of course some applications will require these kind of manipulations to done client side but I’m guessing they’re the exception rather than the rule.
Sam
@Mathew about Ed:
I think he means create the javascript with a dynamic language like PHP e.g.
Say you create your JS files with markers in place that get run through gettext on the server side and are presented as a “normal” JS file to the browser.
James Aylett
You know this, but it’s worth pointing out that using the English version as the key to translation has a couple of problems. Firstly, it’s fairly verbose, but more importantly you can wind up with places where the same phrase should be used in English, but different phrases in another language. At that point, you have to start getting cute with the exact string you use, or fall back on tokens; it’s often easier to manage as tokens throughout (and solves the verbosity problem to an extent). Writing tools to manage the translations isn’t difficult (for one system I wrote a short python script to keep track of the hashes of the ‘primary’ translation from tokens to English — since all the developers wrote English — so you’d know when a translation was out of date or missing; it could pull out the new things to translate, and it wouldn’t be difficult to extent to bundle them off to a translate semi-automatically).
You’ll get collisions using English as the token when you run into homographs – English has a disturbing number of them. For instance, if you had a site of fun things to do with the family, you might want to label ‘Fair’, ‘Circus’ and ‘Tractor competition’. But you’d also want weather forecasts for the days they were on, and might want ‘Rain’, ‘Calm’ or ‘Fair’.
Rory Parle
This is a very good introduction. I realize you said at the outset that, by necessity, you couldn’t cover every detail, but I thought people might be interested in this brief observation about your sprintf function. The way you have currently coded it you’re restricted to putting the variables in the string in a specific order. That probably won’t be a problem in the particular application that you present, but in general it can lead to translators having to use odd-sounding non-standard sentence formations to coerce the variables into the order they’re provided in. What would be better is a system where instead of specifying a string like, “You are ordering s, at a total cost of <strong>%s</strong> gold pieces.”, you could instead say, “You are ordering %{1:s}, at a total cost of <strong>{2:s}</strong> gold pieces.” The numbers in the variable markers represent which variable from the list goes where. That way, translators can put the variables in wherever they need to, even multiple times per variable if they want.
Michel Valdrighi
Very interesting introduction indeed!
James, to disambiguate translation strings, at Skyrock we use what you could call “locale redundancy.”
The principle: you have a base language (in your case, English) with strings like “fair (adj.)” that is itself translated to the same language without the disambiguation. This helps for translations too; for example, if we have a string like “Their posts:”, we’re unsure about languages with genders for the plural pronouns, so we have both “(m) Their posts:” and “(f) Their posts:” in our i10n database.
Matthew
Ed: I’m afraid I don’t follow you. Are you suggesting that upon every change to the stock ordering form, a JavaScript request is made to the server to generate the correct summary text? Of course, everything that is being done server-side has its translations done server-side as well, this is simply about adding i18n to client side code (which as we all know will be added as progressive enhancement :) ); I can’t see what code you could having to write. Obviously, you can e.g. generate your JavaScript automatically from translation .po files; that’s what I do and Rudolph suggested in the paragraph before he finished editing.
James Aylett
Michel – neat :-). That has the advantage of being easier for translators to work with than pure tokens, and (with some care and cleverness around longer strings) probably isn’t much more verbose.
wishcow
Hi guys, I have an alternative suggestion for you.
There is also a gettext implementation for javascript. It works very nicely for us.
Apparently it also has a sprintf like support, but I haven’t tested it yet.
I’ve written a blog post about it: http://wallsoft.blogspot.com/2008/01/gettext-for-php-and-javascript.html
The library can be found here: http://code.google.com/p/gettext-js/
James: Sure; as I use gettext, I found it easiest for my JavaScript to behave similarly to and be more integrated with that, but as you say, token mapping would be possible too.
Rory: Thanks :-) I’d use “%2$s” as that’s what most other sprintf() functions use. As I – sorry, Rudolph – says, there are quite a few fuller JavaScript sprintf() functions on the internet – e.g. Ash Searle’s and alexei’s both include argument reordering.