Recently I’ve been engaged addding internationalization support for a Java project running on top of ZK framework. It’s been a quite interesting experience, and I think it sharing my experience could be useful for other people facing similar problems. So this entry is planned to be a series of posts about internationalization (i18n hereafter). In this first post, I’ll explain what are the GNU gettext utilities and how to use them.

GNU gettext utilities are perhaps the most popular tools for i18n among free and open source projects. Basically, the idea is to mark text to be localized in the source code with some special tag. For instance:

Label lblName = new Label("First name");

Texts to be translated should be wrapped by gettext function which later will be called to retrieve a localized string.

Label lblName = new Label(gettext("First name"));

Generally, it could be convenient ro rename gettext as _ for shorten tags and make them easier to identify in the code.

public String gettext(String str) {
    return gettext(str);
}

There’s a basic set of steps or workflow when working with GNU gettex utilities. First, we mark our source code properly. Then we run command gettext command to parse those marks. The result will be a keys.pot file containing all texts prompt to be translated.

find ./src -name "*.java" -exec xgettext --from-code=utf-8 -k_ -o keys.pot '{}' ;

A keys.pot file has the following structure:

white-space
#  translator-comments
#. extracted-comments
#: reference...
#, flag...
#| msgid previous-untranslated-string
msgid untranslated-string
msgstr translated-string

A simple entry can look like this:

#: src/main/java/com/igalia/UnexpectedError.java:101
msgid "Run-time error"
msgstr "Error en tiempo de ejecución"

Every entry consists of its correspondant msgid, plus a list of comments containing  filename and line** *for every *msgid that happened in the code. Considering that, it can be concluded that every msgid in a .pot file is in fact unique.

Once our keys.pot file has been generated, it’s time to localize it.You can simply copy keys.pot to your destination .po file (es.po,* pt.po, jp.po*, etc.), however the best way to do this is using msginit command:

msginit -l es_ES -o es.po -i keys.pot

In case a locale *.po *file already exists in our project, we can easily updated it by running the following command:

msgmerge -U es.po keys.pot

This will update all missing entries from* .pot* file to .po, so now you’re ready for translating new entries with poedit or your favorite text-editor.

Lastly, we need to turn the .po files into a machine-oriented format, which may yield efficient retrieval of translations by the programs of the package:

msgfmt --java2 -d . -r app.i18n.Messages -l es es.po

Please refer to GNU `gettext’ utilities: 10.1 Invoking the msgfmt Program for more details about parameters invocation.

In my next post, I’ll focus on how to use these tools to give i18n support to a Java project. Till then, have fun.