Internationalization

Internationalization

GLib doesn’t force any particular localization method upon its users. But since GLib itself is localized using the gettext() mechanism, it seems natural to offer the de-facto standard gettext() support macros in an easy-to-use form.

In order to use these macros in an application, you must include <glib/gi18n.h>. For use in a library, you must include <glib/gi18n-lib.h> after defining the GETTEXT_PACKAGE macro suitably for your library:

#define GETTEXT_PACKAGE "gtk4"
#include <glib/gi18n-lib.h>

For an application, note that you also have to call bindtextdomain(), bind_textdomain_codeset(), textdomain() and setlocale() early on in your main() to make gettext() work. For example:

#include <glib/gi18n.h>
#include <locale.h>

int
main (int argc, char **argv)
{
  setlocale (LC_ALL, "");
  bindtextdomain (GETTEXT_PACKAGE, DATADIR "/locale");
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);

  // Rest of your application.
}

where DATADIR is as typically provided by Automake or Meson.

For a library, you only have to call bindtextdomain() and bind_textdomain_codeset() in your initialization function. If your library doesn’t have an initialization function, you can call the functions before the first translated message.

The gettext manual covers details of how to integrate gettext into a project’s build system and workflow.

Macros

GLib provides various convenience C pre-processor macros that make it easy for tools like xgettext to extract translatable strings from the source of a library or an application. These macros are defined when including <glib/gi18n.h> or <glib/gi18n-lib.h>.

_(String)
Marks a string for translation. The string will be replaced by its translation at run time, if any exists; otherwise, it will be passed as is.
N_(String)

Marks a string for translation. Unlike _(), this macro will not replace the string with its translation; this is useful when the translatable string is inside a struct or array declaration, for instance:

static const char *messages[] = {
  N_("some very meaningful message"),
  N_("and another one"),
};

It is the responsibility of the developer to call gettext() when using the string, e.g.:

g_print ("%s", idx >= G_N_ELEMENTS (messages)
         ? _("default message")
         : gettext (messages[idx]));
C_(Context, String)

Uses gettext to get the translation for String. Context is used as a context. This is mainly useful for short strings which may need different translations, depending on the context in which they are used. For instance:

label1 = C_("Navigation", "Back");
label2 = C_("Body part", "Back");

If you are using the C_() macro, you need to make sure that you pass --keyword=C_:1c,2 to xgettext when extracting messages. This only works with a version of GNU gettext newer than 0.15.

This macro is available since GLib 2.16

NC_(Context, String)

Only marks a string for translation, with context. Similar to N_(), but allows you to add a context to the translatable string, for instance:

static const char *messages[] = {
  NC_("some context", "some very meaningful message"),
  NC_("some context", "and another one")
};

It is the responsibility of the developer to call g_dpgettext2() when using the string, e.g.:

g_print ("%s", idx >= G_N_ELEMENTS (messages)
         ? g_dpgettext2 (NULL, "some context", "a default message")
         : g_dpgettext2 (NULL, "some context", messages[idx]);

If you are using the NC_() macro, you need to make sure that you pass --keyword=NC_:1c,2 to xgettext when extracting messages. This only works with a version of GNU gettext newer than 0.15. Intltool has support for the NC_() macro since version 0.40.1.

This macro is available since GLib 2.18

Q_(String)

Like _(), but handles context inside the translatable string. This has the advantage that the string can be adorned with a prefix to guarantee uniqueness and provide context to the translator.

The String is made of two parts, separated by the | character. The leading part is the prefix, which must not be translated; the trailing part is the translatable message.

One use case given in the gettext manual is GUI translation, where one could e.g. disambiguate two ‘Open’ menu entries as "File|Open" and "Printer|Open". Another use case is the string ‘Russian’ which may have to be translated differently depending on whether it’s the name of a character set or a language. This could be solved by using "charset|Russian" and "language|Russian".

See also the C_() macro for a different way to mark up translatable strings with context.

If you are using the Q_() macro, you need to make sure that you pass --keyword=Q_ to xgettext when extracting messages. If you are using a version of GNU gettext newer than 0.15, you can also use --keyword=Q_:1g to let xgettext split the context string off into a msgctxt line in the .po file.

This macro is available since GLib 2.4