How does GNU gettext work?

GNU gettext is based on the mo file format (explained later), and everything is based on a function named gettext(), that can look up the English text in such a file, and find the translation which is also in this file.

The simplest (but not easiest) way to put a translated caption on a label would therefore be:

Label1.Caption:=gettext('Enter username:');

If there is a translation, the translation will be assigned to the label. If there is no translation, or the translation cannot be read for some reason, the text inside the ( ) is used instead.

In order to create an mo file, you write a po file and compile it using the msgfmt compiler. A po file looks like this:

msgid ""
msgstr ""
"Project-Id-Version: Delphi 6 runtime translation\n"
"POT-Creation-Date: 2003-03-04 17:49\n"
"PO-Revision-Date: 2003-04-02 17:48+0100\n"
"Last-Translator: Lars B. Dybdahl <>>\n"
"Language-Team: Dansk <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"License: Freeware\n"

#  This is a comment from the programmer to the translator
#. Programmer's name for it: SInvalidCreateWidget
#: Clx/QConsts.pas:22
msgid "Class %s could not create QT widget"
msgstr "Klassen % kunne ikke oprette en QT widget"

#. Programmer's name for it: STooManyMessageBoxButtons
#: Clx/QConsts.pas:23
msgid "Too many buttons specified for message box"
msgstr "For mange knapper angivet for meddelelsesvindue"

Here, msgid marks the English original text, and msgstr marks the Danish translation. You can write this file using a text editor like notepad, wordpad etc.

As you might already guess, this system can be extended in many ways. The most obvious is that you can have several mo and po files. If an application has more than one file for each language, these are named text domains. The name of a text domain is also the name of an mo file, without the extension. The default text domain is name "default" an must therefore be in the file "", a compilation of "default.po".