Techwriter at work blog.

Living and writing documentation at Documatt, small team of programmers that do write documentation too.

Translating with gettext overview

Localization with gettext is streamlined process with responsibility distributed among original messages author, gettext tooling, and translator or translator tools. This post will help you understand extracting messages and starting new translation.


Step 1 - write a source with messages

Original author writes a programming code or a text. But not every string is to be translated. Strings marked to be translated are called messages in gettext.

For example, in Python code any message passed to a gettext() (usually aliased to _ /underscore/) will be picked up by gettext as message ID. The following example will print the translation of “Mark as completed”, or original string “Mark as complated” if translattion is missing.

import gettext

# setup
gettext.bindtextdomain('chat', 'source/locales/')
_ = gettext.gettext

print(_('Do you want to save the file?'))

In Sphinx documentation, the gettext builder extracts every block-level node to a message (headings, paragraphs, bullet list items, etc.). In the following example, two messages - heading and paragraph - will be extracted:

Hello from Sphinx

This is simple Sphinx document with a heading, *italic* and **bold text**.

Step 2 - extract messages to .pot template

Gettext understands the source and picks up messages to a message catalog template file with .pot extension (“t” as template). This file has identical format as .po but is temporary, without translations and serves only as a starting template for translations to a new langauges.

After running gettext extraction, the .pot file for Python example will looks like (without header):

msgid "Do you want to save the file?"
msgstr ""

.pot file for Sphinx document will looks like (without header):

msgid "Hello from Sphinx"
msgstr ""

msgid "This is simple Sphinx document with a heading, *italic* and **bold text**."
msgstr ""

Since they are temporary and can be anytime generated from the source, you usually don’t put POT files under version control.

Step 3 - start a new translation

Starting a new translation actually means copying POT file to <locales>/<language>/LC_MESSAGES/ folder. For example, chat.pot will become locales/cs/LC_MESSAGES/chat.po. The content of file is the same as POT, i.e. with empty msgstrs.

Step 4 - translation

Translator opens his text editor or specialized tool and starts actual translation of msgid to msgstr in a .po file for a language.

msgid "Do you want to save the file?"
msgstr "...translation of msgid here..."

PO files contain real content and are always versioned.


comments powered by Disqus