Last updated February 1, 2013.
This page gives an introduction to POT and PO files.
Drupal uses the .po (portable object) and .pot (portable object template) extensions for the translation files. These use the GNU Gettext format. The basic difference between these file formats is that .pot files are simply templates which contain no translations while .po files do.
PO files
PO files are the files which contain the actual translations. Each language will have its own PO file, for example, for French there would be a fr.po file, for german there would be a de.po, for American English there might be en-US.po. You can even use po files to customise the displayed text without changing the code, by for example, creating an adapted file such as en-my_company.po.
The core of each PO file is very simple; it is made of simply pairs of the source text - that which is found in the code - and target text, the text which is wanted in the translation. For example, in the French PO file you might have a translation of a string as follows:
msgid "Hello world"
msgstr "Bonjour le monde"
The msgid contains the text actually in the code, and the msgstr contains the text into which it is translated. If there is no translation given in the msgstr, then the default msgid string will be displayed.
PO files are simply text files and can thus be edited by any text editor, but there are also many tools available to make editing them easier.
A Drupal site will usually contain multiple PO files for a single language, which are distributed as a single package. Individual PO files can be imported into the database via http://[your_site]/admin/build/translate/import (Drupal 6) or http://[your_site]/admin/config/regional/translate/import (Drupal 7):
This page imports the translated strings contained in an individual Gettext Portable Object (.po) file. Normally distributed as part of a translation package (each translation package may contain several .po files), a .po file may need to be imported after off-line editing in a Gettext translation editor. Importing an individual .po file may be a lengthy process.
Note that the .po files within a translation package are imported automatically (if available) when new modules or themes are enabled, or as new languages are added. Since this page only allows the import of one .po file at a time, it may be simpler to download and extract a translation package into your Drupal installation directory and add the language (which automatically imports all .po files within the package). Translation packages are available for download on the Drupal translation page.
How do you get a basic PO file with all the original msgid strings in it? That is where the POT files come in.
POT files
POT files are basically the template files for PO files (Warning: Microsoft also uses POT as the extension for PowerPoint template files, but these are not the same). They will have all the translation strings (the msgstr parts) left empty, for example:
msgid "Hello world"
msgstr ""
The French PO file (fr.po) is then simply a copy of the POT file but with the translations filled in. For example, the og module has the following files:
- includes.pot (the template file)
- includes.de.po (a copy of the POT file with translations for German (de)
- includes.ru.po (a copy of the POT file with translations for Russian (ru)
If you need to generate a POT file, the Translation template extractor module will do this.
Examples
Here are examples of these files:
A POT file (i.e. the translation template):
#: modules/user/views_handler_filter_user_name.inc:29
msgid "Enter a comma separated list of user names."
msgstr ""
#: modules/user/views_handler_filter_user_name.inc:112
msgid "Unable to find user: @users"
msgid_plural "Unable to find users: @users"
msgstr[0] ""
msgstr[1] ""A German PO file (i.e. the file containing the translations):
#: modules/user/views_handler_filter_user_name.inc:29
msgid "Enter a comma separated list of user names."
msgstr "Eine kommagetrennte Liste von Benutzernamen."
#: modules/user/views_handler_filter_user_name.inc:112
msgid "Unable to find user: @users"
msgid_plural "Unable to find users: @users"
msgstr[0] "Benutzer konnte nicht gefunden werden: @users"
msgstr[1] "Benutzer konnten nicht gefunden werden: @users"In the second string @users is a variable, and will be replaced with a number in the user interface. Words starting with @, !, and %, as well as words inside {} and expressions like {text}.text are variables and should not be translated.