Gettext is a creation of GNU and is the system by which (almost all) Ubuntu translations are retrieved for display at run time.
It handles what we have covered so far:
Give me a translation of message
For domain (that is, for application, although some applications use multiple domains)
In the current locale
Programming languages provide an API to gettext. For example, C and Python have APIs for gettext.
Gettext provides a translation framework that includes translation catalogs (which are binary files used at run time) and translation files used by Launchpad and in source packages, very important, but discussed later.
Gettext can also be used directly at the command line, as will be done from this point forward for examples.
A Gettext Example
Let's use gettext directly at the command line to obtain a translation:
- Of the message: "File"
- From the GTK 2.0 domain ('gtk20')
- In French
Why "File"? It seems likely that this message is translated in GTK stock widgets, and it actually is.
Is French Installed?
So for simplicity, let's assume we are using Ubuntu and have installed French through Language Support.
We should therefore have the Ubuntu French gtk20.mo file installed: /usr/share/locale-langpack/fr/LC_MESSAGES/gtk20.mo
And we do:
$ ls /usr/share/locale-langpack/fr/LC_MESSAGES/ | grep gtk20\.mo gtk20.mo
If you do not, you can install French with Language Support (or another language, making appropriate adjustments in the examples that follow.)
Switch Command Shell to French
Open a terminal and switch it to French/France locale:
(Note that previously Ubuntu used the LANG variable for translation language. Now LANGUAGE is used for this, and LANG is used to specify other types of locale information, such as date formats, number formats, etc.)
Retrieve French Translation of "File"
Now we are ready to display the French translation with gettext, using its -d DOMAIN argument, as follows:
$ gettext -d gtk20 File Fichier
So, "Fichier" is the gtk20 French translation of "File"!
Taking a closer look:
-d is used to specify the domain: in this case gtk20. (See man gettext)
"File" is the message to be translated (again, see man gettext)
About Singular Strings and Plural Strings
Naturally, gettext supports singular and plural message translation. The API for singular message translation is very straightfoward (described below).
Plural messages are a little more complicated. The message can be singular or plural at run time. For example, "You have requested X files", where X can be any number. Such messages require a variable that states the count. Depending on the count, gettext retrieves the correct form of the translation.
Singular takes this form: gettext(message)
For example (C and Python):
gettext("Translation is important")
Note that gettext is often called with this: "_", for example:
_("Translation is important")
Messages with singular and plural takes this form: ngettext(message-singular, message-plural, count). Because the number of items is usually inside the message, one uses printf style value substitution to pass the run-time number into the message.
For example, C and Python:
ngettext("I found %i error", "I found %i errors", count)
Note that ngettext is often called with this: "N_".
In both examples, if count was equal to 1, and the locale was English (so there is no translation), we would expect to see: "I found 1 error".
If count was equal to 2, and the locale was English, we would expect to see: "I found 2 errors".
Note: You cannot get fancy and try to construct a plural by checking count in code and adding an 's' if count > 1 because many languages form plurals differently, have no plurals, or have more types of plurals than English. It turns out that plurality is widely differing in different human languages, and therefore, unless you are fluent in all the world's languages, it is absolutely necessary to use the ngettext function (and thereby benefit from the tool chain that derives from it.
Gnome addresses plurals in greater detail here.
Do not attempt to cleverly insert a negation "not" into a message because languages form negations in different ways. If you need a negation, make it a separate message. Gnome addresses plurals here.