PO files (Portable Object) are plain-text files used by the Gettext system for software localization and internationalization. PO file format was released initially in 1990, and it's still widely used in many Unix-like systems, and modern frameworks like Django, Ruby on Rails, WordPress, and many others.
PO files are used to store translations for a single language. They contain message ids (translation key), comments, and contexts, and translated messages. We can distinguish two different file formats:
- POT file format (Portable Object Template) is used as a template for translating text, it does not contain translated messages, only message ids, comments, and contexts. You can treat it as a template.
- PO file format is a translation record that contains the same values as a POT file, but it also contains translated strings for a single language.
Recommended settings
Enable 'Use translation keys as translations' import option, if your PO files don't have translations under the msgstr values and your
translations are in msgid. In CLI and API, this option is named USE_KEYS_AS_TRANSLATIONS.
Enable 'Import context as namespace' option for import and 'Use namespace as message context' option for export, if
you use msgctxt in your PO/POT files. This will allow distinguishing different translations with the same msgid.
In CLI and API, both options are named MSGCTXT_AS_NAMESPACE.
File format example
Each translation unit consists of a message id, a message string, and optional metadata like comments, contexts, and plural forms.
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=3; plural=(n == 1 ? 0 : (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2));\n"
"Language: pl\n"
# Single line
msgctxt "Translation context"
msgid "Translation key"
msgstr "Translation message"
# Multiple lines
msgid ""
"The input text "
"split to several "
"lines"
msgstr ""
"Translation "
"can also be splitted."
Many PO files contain metadata at the beginning of the file, which is used to describe the file format, language, and plural forms. The metadata is stored in the form of key-value pairs, separated by colons.
In the example above, the metadata contains the following keys:
Content-Type- specifies the content type of the filePlural-Forms- specifies the plural forms used in the fileLanguage- specifies the language of the translations
Some frameworks and tools require the metadata to be present in the file,
for example, the Plural-Forms and Content-Type headers are required by the Gettext library.
Message id
The message id is the original text that needs to be translated.
msgid "Hello, world!"
Message string
The message string is the translated text that corresponds to the message id.
msgstr "Witaj, świecie!"
Context
The context is used to provide additional information about the translation.
msgctxt "Greeting"
msgid "Hello"
msgstr "Witaj"
If you use
msgctxtto distinguish different translations with the samemsgid, consider importing the context as namespace in SimpleLocalize. You can find 'Import context as namespace' option in the import settings.
Plural forms
Plural forms are used to handle different grammatical forms of the same word.
The plural form is defined in the Plural-Forms header, which contains a formula that determines the correct plural form based on the number of items.
msgid "There is one apple"
msgid_plural "There are %d apples"
msgstr[0] "Jest jedno jabłko"
msgstr[1] "Są %d jabłka"
msgstr[2] "Są %d jabłek"
SimpleLocalize fills the Plural-Forms header automatically for the language for which the translations are exported.
Comments
Comments in PO files can be single-line or multi-line.
They can be used to describe the context of the translation,
provide additional information. Comments are prefixed with a hash sign #, #., #: or #,.
# This is a translator comment
#. Translators: This message appears on the home page only
#: mysite/views.py:7 templates/home.html:12
#, python-format
#- translator comment, written by hand in the PO file#.- extracted comment, added byxgettextfrom the source code to provide additional information about the message#:- reference comment, used to specify the location of the message in the code#,- flags, e.g.python-format,c-formatorfuzzy
On import, the translator comment (#) becomes the key description. If there is no translator
comment, the extracted comment (#.) is used instead. On export, the key description is written back as a # comment
(or as #. with the REFERENCE_COMMENTS export option).
Metadata stored in key attributes
SimpleLocalize keeps the remaining gettext metadata in the translation key attributes under the po-pot key,
so that it survives the round trip between your repository and the Translation Editor and can be used as context for
auto-translation:
{
"po-pot": {
"msgctxt": "Greeting",
"references": ["mysite/views.py:7", "templates/home.html:12"],
"flags": ["python-format"],
"translator-comment": "This is a translator comment",
"extracted-comment": "Translators: This message appears on the home page only"
}
}
msgctxt- message context, unless you import the context as namespacereferences- all#:locations of the message in the codeflags- format flags from#,; thefuzzyflag is not stored, because it describes a single translation rather than the messagetranslator-commentandextracted-comment- both comments kept separately, with line breaks preserved
Attributes are stored per translation key, not per language, so the values from the most recently imported PO file are kept.
Imports only replace the po-pot entry and leave attributes from other sources, such as Figma or other file formats, untouched.
On export, all of them are written back to the PO file. Keys without any gettext metadata are exported exactly as before.
Example gettext usage
printf(gettext("Hello world! I'm %s.\n"), application_title);
printf(_("Hello world! I'm %s.\n"), application_title);
Upload with CLI
Upload source language translations to SimpleLocalize using CLI.
simplelocalize upload --apiKey PROJECT_API_KEY \
--uploadFormat po-pot \
--uploadLanguageKey en \
--uploadPath ./messages_en.po
Learn more about SimpleLocalize CLI and translations upload feature.
Download with CLI
simplelocalize download --apiKey <PROJECT_API_KEY> \
--downloadFormat po-pot \
--downloadLanguageKey pl,fr,de \
--downloadPath ./messages_{lang}.po
Learn more about SimpleLocalize CLI and translations download feature.