Supported File Types (Strings)

.PO - gettext files (Strings)

File Extensions

.po

API Extension

gettext

Import

Yes

Export

Yes

Plural forms support

Yes

Description support

Yes

.PO (Portable Object) is the standard file format for localization with GNU gettext, an open-source GNU library designed to simplify the localization process. With GNU gettext, localizable strings are extracted from source code into a PO file for translation. A .PO file is a series of key-value pairs. The key msgid is where the source string is put while the value msgtr is where the translation goes.

gettext extracts strings from source code into a .POT (portable object template). Based on defined locales, gettext then converts the .POT file into a locale-specific .PO files for upload to a CAT tool for translation. After translation, gettext converts the translated .PO files into .MO files (machine object files) eventually used for localization.

.PO files are identical to .POT files excepting .POT files are mostly used by gettext to generate locale-specific .PO files. Translating a .POT file directly and renaming it according to the later intended locale does not cause any problems. Phrase supports the translation of .PO .POT and the machine-readable .MO files.

Code Sample

msgid ""
msgstr ""
"Language: English\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: PhraseApp (phraseapp.com)\n"

msgid "boolean_key"
msgstr "--- true\n"

msgid "empty_string_translation"
msgstr ""

# This is the amazing description for this key!
msgid "key_with_description"
msgstr "Check it out! This key has a description! (At least in some formats)"

msgid "key_with_line-break"
msgstr "This translations contains\na line-break."

msgid "nested.deeply.key"
msgstr "Wow, this key is nested even deeper."

msgid "nested.key"
msgstr "This key is nested inside a namespace."

msgid "null_translation"
msgstr ""

msgid "pluralized_key"
msgid_plural ""
msgstr[0] "Only one pluralization found."
msgstr[1] "Wow, you have %s pluralizations!"

msgid "sample_collection"
msgstr "---\n- first item\n- second item\n- third item\n"

msgid "simple_key"
msgstr "simple key, simple message, so simple.2"

#, fuzzy
msgid "unverified_key"
msgstr "I need verification, please verify me! (In some formats we also export this status)"

Typical gettext entry:

# description (Optional)
msgid "key-name"
msgstr "My Translation"

gettext Header

The header of a gettext file may contain a locale name and data for plural forms that is extracted during import:

msgid ""
msgstr ""
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: PhraseApp (phraseapp.com)\n"

Descriptions

Comments in a gettext file are added as key descriptions during import:

# This is my description
msgid "app_title"
msgstr "My Software Project"

Context

gettext uses the msgctxt notation to distinguish different contexts for the same msgid. Every key name must be unique so msgctxt is added as the first part of the key name, separated by two pipe symbols ||:

msgctxt "menu"
msgid "Open"
msgstr "I'am a translation"

msgctxt "forum"
msgid "Open"
msgstr "I'am some other translation"

To add the msgctxt to a new key, prepend it to the key name:

my_context||my_key_name

Resulting gettext output:

...
msgctxt "my_context"
msgid "my_key_name"
...

Plural forms

gettext supports plural forms for a translation:

msgid "new_messages"
msgid_plural ""
msgstr[0] "You have a new message"
msgstr[1] "You have %{count} new messages"

Fuzzy

The fuzzy keyword is used for translator verification. Fuzzy automatically invokes the unverification process within the app.

#, fuzzy
msgid "app_title"
msgstr "My Software Project"
Was this article helpful?

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.