Translate GNU Gettext PO Files Online Without Losing Headers & Plurals
GNU Gettext portable object (.po) files are widely used across Python (Django), C++, PHP (WordPress), and Linux software. Translating PO files with raw translation tools breaks msgid keys, context tags (msgctx), and sprintf specifiers (%s). Learn the safe PO translation and PO-to-XLIFF workflow.
TL;DR — Key Takeaways
- In Gettext,
msgidis your source key. Translatingmsgidcauses gettext lookup failure at runtime. - Only
msgstrstrings should be modified whilemsgctx, comments (#:), and headers stay locked. - Convert PO to XLIFF for professional translation agencies or use StrucTrans for instant AST-safe web translation.
Why Naive Translation Breaks Gettext PO Files
GNU Gettext relies on strict header syntax and structural tokens to compile binary .mo files:
Mangled msgid Keys
If msgid "User Settings" is translated to Spanish in place, the Gettext runtime won't match the original English string passed from source code calls like _("User Settings").
Stripped msgctx Context
Contextual disambiguation tags like msgctx "button" vs msgctx "menu" are stripped by plain text tools, leading to wrong translations.
Broken sprintf Placeholders
Format specifiers like %s, %d, or Python named placeholders %(username)s get altered, throwing runtime string format exceptions.
Raw Machine Translation vs StrucTrans AST-Safe PO Output
msgctx "botón"
msgid "Guardar archivo"
msgstr "Guardar archivo"
msgid_plural "archivos"
msgstr[0] "% s archivo guardado" msgid & msgctx translated into Spanish, %s broken with extra space.
msgctx "button"
msgid "Save file"
msgstr "Guardar archivo"
msgid_plural "Save files"
msgstr[0] "%d archivo guardado"
msgstr[1] "%d archivos guardados" msgid & msgctx locked, plural forms & format specifiers preserved 100%.
Complete Gettext PO & XLIFF Translation Workflow
Follow this step-by-step pipeline to extract, translate, and compile PO files.
Extract Source Strings to POT/PO
Use standard GNU gettext tools like xgettext or Django's makemessages to generate your base template file (messages.po):
$ xgettext --from-code=UTF-8 -o locale/en/LC_MESSAGES/django.po src/*.py Option A: Translate Directly Online with StrucTrans
Upload your django.po file to StrucTrans PO Translator. StrucTrans will read header information, lock all msgid entries, and safely populate msgstr for your chosen target languages.
Option B: Convert PO to XLIFF for Enterprise Workflow
If working with external translation vendors or enterprise CAT software, convert your PO file to standard XLIFF using StrucTrans PO to XLIFF Converter.
Compile PO into Binary MO Files
Once translated, compile the .po file into binary .mo format using msgfmt:
$ msgfmt -o locale/es/LC_MESSAGES/django.mo locale/es/LC_MESSAGES/django.po
Because syntax integrity and plural headers were preserved, msgfmt compiles cleanly without syntax warnings or errors.
Frequently Asked Questions
How do I translate GNU Gettext .po files online without corrupting msgid?
In Gettext, msgid acts as the unique lookup key. Translating msgid destroys string lookup in your backend. StrucTrans locks msgid, msgctx, and PO header metadata, populating only the msgstr values.
Does auto-translation support Gettext plural forms (msgstr[0], msgstr[1])?
Yes. Gettext plural entries use indexed arrays like msgstr[0] and msgstr[1] guided by the Plural-Forms header. StrucTrans respects plural rules for every target language.
Why convert PO to XLIFF before enterprise translation?
XLIFF (XML Localisation Interchange File Format) is an open standard designed for professional translation tools and TMS pipelines. Converting PO to XLIFF isolates source text from PO file comments (#:) and context tags.
Is StrucTrans free for Python, Django, and PHP developers?
Yes. You can upload, translate, and convert Gettext .po files directly in your browser without registration.
Translate Your Gettext PO Files Safely
Preserve headers, msgid lookups, and plural rules while translating Python, PHP, or C++ apps.