• Documentation
  • File formats
  • Gettext (PO)

Gettext (PO)

  • File extension: .po, .pot
  • i18n type: PO

PO files are used by the gettext i18n system. The gettext system has many features, including support for developer comments, context, and the ability to specify the location of a string in the source code.

Whenever a PO file is uploaded, Transifex tries to make sure the file is syntaxically correct. However, you can still check the file for syntax errors using the msgfmt tool that comes with gettext.

# FIRST AUTHOR <email@address>, YEAR.
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-06-08 10:12+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <email@address>\n"
"Language-Team: LANGUAGE <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: actionlog/templates/object_action_list.html:7 txpermissions/
msgid "User"
msgstr ""

#: actionlog/templates/object_action_list.html:8
msgid "Action"
msgstr ""

#: foo/templates/bar.html:180
msgid "{0} result"
msgid_plural "{0} results"
msgstr[0] ""
msgstr[1] ""

Transifex needs the PO files that are uploaded to Transifex to be syntactically correct.

The gettext toolchain comes with a utility to check a PO file for syntax errors, msgfmt, which is available for both Windows and Unix. However, the latest version of the utility (and the one Transifex uses) is available only for UNIX systems.

You can check a PO file for syntax errors by running the command:

msgfmt -c <file.po>

Plural Forms in a PO file

There are many languages that have more than one plural form (English, Russian, Arabic etc.). 

In order to translate .po files using our localization management platform, you need to make sure that the correct number of plural forms has properly been defined in your .po file for the locale it contains. 

So, there are 2 things you need to take care of: 

  • Make sure that your .po file contains the Plural-Forms line in the header entry. This line contains the number of plural forms and a formula.

Example #1: English (one, other)

"Plural-Forms: nplurals=2; plural=(n != 1);\n"

Example #2: Croatian (one, few, other)

"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"

Example #3: Russian (one, few, many, other)

"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"

Example #4: Arabic (zero, one, two, few, many, other)

"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
  • Ensure that each pluralized entry contains a msgstr line for each of the plural forms

Example #1: English (one, other)

#, python-format
msgid "%s day"
msgid_plural "%s days"
msgstr[0] "%s day"
msgstr[1] "%s days"

Example #2: Croatian (one, few, other)

#, python-format
msgid "%s day"
msgid_plural "%s days"
msgstr[0] "%s dan"
msgstr[1] "%s dana"
msgstr[2] "%s dana"

Example #3: Russian (one, few, many, other)

#, python-format
msgid "%s day"
msgid_plural "%s days"
msgstr[0] "%s день"
msgstr[1] "%s дня"
msgstr[2] "%s дней"
msgstr[3] "%s дней"

Example #4: Arabic (zero, one, two, few, many, other)

#, python-format
msgid "%s day"
msgid_plural "%s days"
msgstr[0] "%.0sأقل من يوم"
msgstr[1] "%.0sيوم واحد"
msgstr[2] "%.0sيومان"
msgstr[3] "%s أيام"
msgstr[4] "%s يومًا"
msgstr[5] "%s يوم"