11 comments

[ 4.2 ms ] story [ 34.8 ms ] thread
I know it's in the URL, but I really think the title should mention "JavaScript" just to make it a good free-standing title.
Thanks for the tip! Not sure I can edit the title after posting it though =(
It's really basic, the last time I needed this level of translation-capabilities, I wrote it myself.

Currently I can recommend http://formatjs.io/. We use it with the react-wrapper and it works really good. It handles everything from ICU-capabilites to formatting dates/currencies.

I agree that the functionality provided is quite basic, there are quite a few libraries out there that provide much more functionality, such as the one you mentioned or http://i18next.com/

I was initially using another tiny library http://airbnb.io/polyglot.js/, but we wanted to support translation fallbacks to allow us to put every widget/component in a separate namespace. Which means we don't have to copy translations over unless they are unique, since that became a bit of a maintenance burden as more things are added.

We already supported dates by using separate other libraries such as http://momentjs.com/

Whenever I look at modern internationalization libraries and compare them to GNU gettext, I feel like a key piece of knowledge got lost somewhere. BabelBox continues the trend of apparently not having ever used gettext or understanding how it should work. Here's how it works in gettext. Let's say you have something that prints a message:

    print("Hello, world.");
If a string should be translated, you wrap it in a call to gettext:

    print(gettext("Hello, world."));
In a webapp, you'd need an extra parameter for the session or locale, but the principle is the same. Note that the parameter was the initial english text. This is the first way i18n libraries go wrong: they make the parameter a key, instead of the english message.

    print(i18lib("hello_msg"));
This makes the code less readable, and forces you to update a second location to add the English version. It also means you can no longer search the code for an english-language string and get to the right line.

I guess forcing the developer to update that second location is the reason for doing it that way, but gettext does something better: you run a tool on your source code which automatically detects calls to the gettext function, and produces a file with all the strings, ready to hand off to translators. This is ridiculously much more programmer-friendly.

Templating adds a bunch of complexity to this, and languages have weird quirks that sometimes need to be handled with code. But it's sad that the basics got forgotten.

The problem with using the English message as the key is that, when we changed the English text, we'd have to change the keys in all other languages as well. Also, the same English text might translate to different texts in a foreign language depending on the context / location appeared.

Disclaimer: I've never used gettext before.

And also sometimes a key id is fine because you can add some context in the key like login_welcome signup_welcome. You can also use for grouping strings belonging to the same section: login_welcome, login_callToAction
I've been using gettext for a long time, and used to think like you. But I'm slowly changing my mind.

The problem with gettext is that, when you change the English text, it also changes the ID of all translations. Moreover, it's often necessary to complete the English text with a short string describing the context, to avoid any confusion between two identical strings in different contexts (for example "open" can have several meaning).

When you use a "technical" ID for each translation, you don't have these problems anymore. You can fix a typo in the English translation without checking translations marked "fuzzy" in other languages. You can also include some context in the ID.

But the main advantage of using "technical" IDs it that you get a clear separation between the programmer and the product designer. The programmer doesn't need to spend too much time choosing the right wording, and can focus on the code. The product designer can work on the wording independently without bothering the designer.

I note that the approach advocated by gettext is very popular among open source projects. It's not a coincidence. Programmers working on open source projects are usually the ones writing the text displayed in the user interface.

I note that Java and .Net mainly advocate the "technical" ID approach. It's not a coincidence either. In most IT projects, the text displayed in the user interface is not written by the programmer, but by some project manager or some product designer.

It's perfectly possible to have a tool that scans your source code and automatically detects the calls to the translation function, even if you use "technical" IDs. Here is an example: http://glebm.github.io/i18n-tasks/

You hit the nail on the head here. In particular the points about changing the English text and about different contexts resulting in different translations.

I also feel that the gettext approach assumes everyone speaks the same base language (namely English), but that's not necessarily true with an international team. Obviously the string IDs still need to be in a common language, but those are simpler to parse and search for than full sentences, especially if the person writing the English text has chosen uncommon words or syntax.

Thanks!

I agree with you that the gettext approach relies on the assumption that everyone speaks the same language. I would add that it also relies on the assumption that every programmer has good writing skills, which is not always the case. In my teams, some programmers are really good at writing code, but not so good at writing a correct English or French sentence. In such a situation, string IDs are better.