Chapter 24. Internationalization and Localization

## Chapter 24. Internationalization and Localization

gtkmm applications can easily support multiple languages, including non-European 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, sometimes abbreviated as `l10n`, provides translated text for other languages, based on that source code.

The main activity in the internationalization process is finding strings seen by users and marking them for translation. You do not need to do it all at once - if you set up the necessary project infrastructure correctly then your application will work normally regardless of how many strings you've covered.

String literals should be typed in the source code in English, but surrounded by a macro. The gettext (or intltool) utility can then extract the marked strings for tramslation, and substitute the translated text at runtime.

## Preparing your project

| Note
In the instructions below we will assume that you will not be using gettext directly, but intltool, which was written specifically for `GNOME`. intltool uses `gettext()`, which extracts strings from source code, but intltool can also combine strings from other files, for example from desktop menu details, and GUI resource files such as Glade files, into standard gettext`.pot/.po` files. We also assume that you are using `./autogen.sh` from gnome-common, which, among other things, takes care of some intltool initialization.

Create a `po` sub-directory in your project's root directory. Within it, create `LINGUAS` and `POTFILES.in` files, as well as a `ChangeLog` file so that translators can keep track of translation changes.

`LINGUAS` contains an alphabetically sorted list of codes identifying the languages for which your program is translated.

`POTFILES.in` is a list of paths to all files which contain strings marked up for translation, starting from the project root directory. So for example, the entries would look like:

          src/main.cc
          src/other.cc

If you have designed some of the application UI in Glade then also add your `.glade` files to the list in `POTFILES.in`.

Add the following code to your `configure.ac`, substituting 'programname' with the name of your program:

          IT_PROG_INTLTOOL([0.35.0])

          GETTEXT_PACKAGE=programname
          AC_SUBST(GETTEXT_PACKAGE)
          AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [The domain to use with gettext])
          AM_GLIB_GNU_GETTEXT

          PROGRAMNAME_LOCALEDIR=[${datadir}/locale]
          AC_SUBST(PROGRAMNAME_LOCALEDIR)

This PROGRAMNAME_LOCALEDIR variable will be used later in the Makefile.am file, to define a macro that will be used in our source code, to initialize gettext.

In the top-level Makefile.am:

- Add `po` to the `SUBDIRS` variable.
- Define `INTLTOOL_FILES` as:

                  INTLTOOL_FILES = intltool-extract.in intltool-merge.in intltool-update.in

- Add `INTLTOOL_FILES` to the `EXTRA_DIST` list of files.
- Update your `DISTCLEANFILES`:

                  DISTCLEANFILES = ... intltool-extract intltool-merge intltool-update po/.intltool-merge-cache

In your `src/Makefile.am`, update your `AM_CPPFLAGS`:

          AM_CPPFLAGS = ... -DPROGRAMNAME_LOCALEDIR=\"${PROGRAMNAME_LOCALEDIR}\"

Using derived widgets |  | Marking strings for translation