Chapter 20. Internationalization and Localization

Table of Contents

English in the source code, translations in the .po files.
gettext
Expecting UTF8
Glib::ustring and std::iostreams
Pitfalls
Same strings, different semantics
Composition of strings
Assuming the displayed size of strings
Unusual words
Using non-ASCII characters in strings
Getting help with translations

gtkmm applications can easily support multiple languages, including non-ASCII languages such as Chinese and right-to-left languages such as Arabic. An appropriately-written gtkmm application will use the appropriate language at runtime based on the user's environment.

You might not anticipate the need to support additional languages, but you can never rule it out. And it's easier to develop the application properly in the first place rather than retrofitting later.

The process of writing source code that allows for translation is called internationalization, often abbreviated to i18n. The Localization process provides translated text for other languages, based on that source code.

English in the source code, translations in the .po files.

String literals should be typed in the source code in english as normal, but they should be surrounded by a call to the gettext() function. These strings will be extracted for translation and the translations may be used at runtime instead of the original english strings.


Google

gettext

The GNU gettext package allows you to mark strings in source code, extract those strings for translation, and use the translated strings in your application.

Call gettext() with the string literals that should be translated. For example:

window.set_title(gettext("My application"));	  
label.set_text(gettext("This is some text"));

Using gettext() throughout your source code can make it harder to read, so many projects, such as GNOME define the shorter _() macro that does the same thing. For instance,

window.set_title(_("My application"));	  
label.set_text(_("This is some text"));

How gettext works

xgettext script extracts the strings and put them in a mypackage.pot file. The translators of your application create their translations by first copying this .pot file to languagename.po files. A locale identifies a language and an encoding for that language, including date and numerical formats. Later, when the text in your source code has changed, the msmerge script is used to update the localename.po files from the regnerated .pot file.

At install time, the .po files are converted to a binary format (with the extension .mo) and placed in a system-wide directory for locale files.

When the application runs, the gettext library checks the system-wide directory to see if there is a .mo file for the user's locale environment (you can set the locale with, for instance, "export LANG=de_DE.UTF-8" from a bash console). Later, when the program reaches a gettext call, it looks for a translation. If none is found, the original string is used.

gettext and build files

To use gettext, you need to modify your application's build files, to use the gettext library, to generate the .pot file, and to install the translations from the .po files.

  1. Run getttextize --force --copy --intl - you should add this to your autogen.sh script. This creates the po and intl subdirectories, among other things.
  2. Create po/Makevars, by copying po/Makevars.template and editing it.
  3. Add AM_GNU_GETTEXT to your configure.in
  4. Define AM_LINGUAS in your configure.in, listing the locales for which .po translations exist in your po directory.
  5. Add intl and po to the SUBDIRS in your top-level Makefile.am