Marking strings for translation
| Chapter 27. Internationalization and Localization |

## Marking strings for translation

String literals should be typed in the source code in English, 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.

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.

However, Glib defines `gettext()` support macros which are shorter wrappers in an easy-to-use form. To use these macros, include `<glibmm/i18n.h>`, and then, for example, substitute:

    display_message("Getting ready for i18n.");

with:

    display_message(_("Getting ready for i18n."));

For reference, it is possible to generate a file which contains all strings which appear in your code, even if they are not marked for translation, together with file name and line number references. To generate such a file named `my-strings`, execute the following command, within the source code directory:

    xgettext -a -o my-strings --omit-header *.cc *.h

Finally, to let you program use the translation for the current locale, add this code to the beginning of your `main.cc` file, to initialize gettext.

    bindtextdomain(GETTEXT_PACKAGE, PROGRAMNAME_LOCALEDIR);
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
    textdomain(GETTEXT_PACKAGE);

### How gettext works

intltool / xgettext script extracts the strings and puts them in a `mypackage.pot` file. The translators of your application create their translations by first copying this `.pot` file to a `localename.po` file. 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 regenerated `.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, for example `/usr/share/locale/`.

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 of a particular string. If none is found, the original string is used.

### Testing and adding translations

To convince yourself that you've done well, you may wish to add a translation for a new locale. In order to do that, go to the `po` subdirectory of your project and execute the following command:

    intltool-update --pot

That will create a file named `programname.pot`. Now copy that file to `languagecode.po`, such as `de.po` or `hu.po`. Also add that language code to `LINGUAS`. The `.po` file contains a header and a list of English strings, with space for the translated strings to be entered. Make sure you set the encoding of the `.po` file (specified in the header, but also as content) to `UTF-8`.

| Note
It's possible that certain strings will be marked as `fuzzy` in the `.po` file. These translations will not substitute the original string. To make them appear, simply remove the `fuzzy` tag.

### Resources

More information about what lies behind the internationalization and localization process is presented and demonstrated in:

- Internationalizing GNOME applications

- Intltool README

- How to use GNOME CVS as a Translator

- gettext manual

- `gtkmm_hello` example package

- `gnomemm_hello` example package

Chapter 27. Internationalization and Localization |  | Expecting UTF8