Doing localization on maemo

Overview

This document has been reviewed for maemo 3.x.

This document describes how to localize maemo applications. Localization is needed to provide native translations of the software. The document contains information how to localize an application, how to ease extraction of message strings, how to make the translations and how to test the localization.

Changes are presented with code examples to help the localization process.

Localization

Localization means translating the application to different languages. On maemo localization is based on standard gettext package, and all the necessary tools are included in scratchbox. For applications localization needs couple of files to work which will be in po/ directory. The following files will be used for localization:

Makefile.am	
en_GB.po
POTFILES.in
			

POTFILES.in contains the list of source code files which will be localized. File en_GB.po includes translated text for target en_GB.

Localizing your application

To localize your application you need to set up l10n before gtk_init by including the following headers.


#include <libintl.h>
#include <locale.h>

To initialize the locale functions you need to as well add the following lines.


setlocale(LC_ALL, "");
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);

The most imporant of these are the GETTEXT_PACKAGE and LOCALEDIR that come from configure.ac which should define at least following.


localedir=/usr/share/locale
AC_PROG_INTLTOOL([0.23])
GETTEXT_PACKAGE=maemopad
AC_SUBST( GETTEXT_PACKAGE )
ALL_LINGUAS="en_GB"
AM_GLIB_GNU_GETTEXT

Of these you only really need to pay attention to GETTEXT_PACKAGE, as it is the l10n domain you want to use, and ALL_LINGUAS lists the translations you have available.

If you are building applications for maemo 1.0, set localedir to /var/lib/install/share/locale.

Easing the extraction of strings

In your source code, you have strings littered all over, which eventually get shown in the user interface. For example:


hildon_app_set_title ( app, "MaemoPad" ); 

In order to make your strings localizable, you need to wrap the strings you want translated in gettext("String") calls. In practice, writing gettext() for every string is tedious. The common practice is to set the following #define


#define _(String) gettext (String)

Thus the i18n version of the example would be:


hildon_app_set_title ( app, _("MaemoPad") );

Creating translation files

Creating *.po files is quite straightforward. We use Maemopad as an example. Maemopad only has one localization file, en_GB.po, others like fi_FI.po can be easily made based on this. Localization .po files are filled with simple structure, which defines the localization id and the actual text string. Sample of this structure is as follows:


#: src/document.c:727 src/document.c:733
msgid "note_ib_autosave_recover_failed"
msgstr "Recovering autosaved file failed"
			

"msgid" defines the original string (key) used in code and "msgstr" defines the translated string for localization.

First we create a template file with all strings from sources for translation. We use GNU xgettext command [9] to extract the strings from sources:

"xgettext -f POTFILES.in -C -a -o template.po"

Option "-f POTFILES.in" uses POTFILES.in to get the files to be localized, "-C" is for C-code type of strings, "-a" is for ensuring that we get all strings from sources and "-o template.po" defines the output filename.

This may output some warnings which usually are not serious, but it is better to check them anyway.

If you want to translate to Finnish, copy the edited po/template.pot to po/fi_FI.po and add fi_FI.po to ALL_LINGUAS in configure.ac.

now po/fi_FI.po will include lines like the following:


#: ../src/ui/interface.c:123
msgid "maemopad_save_changes_made"
msgstr "Save changes?"
			

Translate all msgstrings to the language you are translating to:


#: ../src/ui/interface.c:123
msgid "maemopad_save_changes_made"
msgstr "Tallenna muutokset?"
			

Autotools should now automatically convert the .po file to .mo file during the build process, and install it to the correct location.

In case you want to do it yourself:


msgfmt po/fi_FI.po -o debian/maemopad/share/locale/fi_FI/LC_MESSAGES/domain.mo
			

Where "debian/maemopad/share/locale/fi_FI/LC_MESSAGES/" is the directory you want to install software to.

You can find all the necessary files as an example in stage.maemo.org under maemo_testing/maemopad/.

Testing

Inside scratchbox, test your translated application by setting LC_ALL environment variable to contain your newly created locale (in our example case for Finnish translation, "fi_FI"):


LC_ALL="fi_FI" run-standalone.sh ./maemopad
			

On the target device, you will need a wrapper script to accomplish this, if the device does not have a locale for the locale identifier you used. The script can simply consist of:


#!/bin/sh
LC_ALL="fi_FI" /usr/bin/maemopad
			

The above example assumes that your installation package installs the executable into /usr/bin. This script needs to be then configured to be run in the application's .desktop file instead of the actual executable.



Improve this page