Internationalisation, or i18n for short, is the process of making the user interface of a program ready for translation into multiple languages. This usually means to factor out texts from the program source code into separate files, often called translation bundles. These files have a key-value structure. The program code then only refers to keys that are resolved into the actual texts from the translation bundle for the selected target language.
Here’s a simple example of two translation bundles, one for English and one for German:
# translations_en.properties
quit_confirm_message=Do you really want to quit?
yes_option=Yes
no_option=No
# translations_de.properties
quit_confirm_message=Wollen Sie die Anwendung wirklich beenden?
yes_option=Ja
no_option=Nein
The actual source code might look like this:
var answer = showDialog(
t("quit_confirm_message"),
t("yes_option"),
t("no_option")
);
Here the function t
looks up the key in the currently active translation bundle and returns the translated message as a string.
How not to do it
Last month I discovered an amusing attempt at internationalisation in a third-party code base. It looked similar to this:
# translations_en.properties
a=A
an=An
is=is
not=not
available=available
article=article
# translations_de.properties
a=Ein
an=Ein
is=ist
not=nicht
available=verfügbar
article=Artikel
These translation keys were used like this:
"${t('an')} ${t('article')} ${t('is')}
${available ? '' : t('not')} ${t('available')}."
to produce messages like
"An article is available."
"An article is not available."
… or in German:
"Ein Artikel ist verfügbar."
"Ein Artikel ist nicht verfügbar."
Why is this a clumsy attempt at internationalisation?
Because it uses single words as translation units, and it relies on the fact that English and German have the same sentence structure in this particular case. In general, of course, languages do not have the same sentence structure, not even related languages like English and German.
The author of the code also introduced separate translation keys for “a” and “an”. The German translation for both keys was “ein”. The author was lucky so far that all texts with “a” or “an” in this particular program translated to “ein” in German, not “eine”, “einen”, “einem”, “einer”, or “eines”.
How to do it
So what would be the correct way to do it? The internationalisation should have looked like this:
# translations_en.properties
article_available=An article is available.
article_not_available=An article is not available.
# translations_de.properties
article_available=Ein Artikel ist verfügbar.
article_not_available=Ein Artikel ist nicht verfügbar.
available ? t("article_available")
: t("article_not_available")
By using whole phrases and sentences as translation units the translations into various languages have the freedom to use their own word orders and grammatical structures.