Internationalization¶
Translate the explanation while keeping its structure. Guidedog extracts message catalogs, merges translations, and builds for a chosen language. The source text stays the reference. A missing translation falls back rather than inventing text.
The workflow¶
-
Write the message templates with the
gettextbuilder:guidedog build gettext
It writes one template (
.pot) per text domain into_build/gettext: every paragraph, title, list item, table cell, caption, admonition, term, and field of the documents becomes a message, with the file and line it comes from. -
Create or update the catalogs of each language, as
sphinx-intl updatedoes:guidedog intl update -l de -l fr
The catalogs appear in
locales/de/LC_MESSAGES/*.po. On later runs the command merges the new templates into them, asmsgmergedoes: translations are kept, a message whose source changed gets the old translation marked fuzzy for review, and messages no longer in the documents are kept at the end as obsolete (#~), so a translation can come back. -
Translate: fill in each
msgstr. Remove the#, fuzzyline of a message once its translation is right; fuzzy translations are not used.msgid "Hello *world*, see the site_." msgstr "Hallo *Welt*, siehe site_."
-
See how far the translation is, as
sphinx-intl statdoes:guidedog intl stat -l de
-
Build in the language:
guidedog build html -D language=de guidedog build pdf -D language=de
or set
language = "de"inconf.toml.Each book has a language suffix:
manual.pdfbecomesmanual-de.pdf. A build publishes one complete generation, so use separate destinations to keep several editions. For example, build German withguidedog build -b pdf docs build/books/de -D language=deand English withguidedog build -b pdf docs build/books/en -D language=en.
Only the documents whose catalog changed are read again, as with any other input of a document; adding or removing a catalog reads every document again.
guidedog intl takes sphinx-intl’s options: -p DIR for the templates (default
_build/gettext), -l LANG, repeatable (default: the project’s language), -d DIR for the catalogs (default: the first of locale_dirs), -w N for the line
width (default 76), and --no-obsolete.
Writing translations¶
A message is the source text of a paragraph, title, or other element, with its markup:
reStructuredText in .rst documents, Markdown in .md ones. A translation is read
in the same markup, so it may emphasize, link, and refer as the original does.
References must stay the same. A translation keeps every reference of its message, written the same way, and may only change the text around them and their titles:
msgid "See :ref:`install` and the site_."
msgstr "Siehe :ref:`Installation <install>` und die site_."
When a translation drops a reference, the build warns (inconsistent references in translated message, as Sphinx does) and uses the translation. When it names a
reference the original does not have, it could not be resolved, so the build warns and
keeps the original text. A translation whose markup the reader refuses is also kept in
the original, with a warning that quotes it.
Section anchors do not change with the language: a translated title keeps the anchor of its original, so links into the site, from inside and outside, keep working.
Settings¶
The standard settings have Sphinx’s names and defaults. Guidedog also provides an extraction-only exclusion setting for untranslated reference appendices.
| Setting | Meaning |
|---|---|
language |
The language to build in, such as "de" or "pt_BR". |
locale_dirs |
Where the catalogs are, relative to the source folder: each holds
LANGUAGE/LC_MESSAGES/DOMAIN.po (or a compiled .mo). Default
["locales"]. With several, the first that translates a message wins. |
gettext_compact |
Which catalog a document’s messages go to. true (the default): a document at
the top level has its own, and the documents of a folder share the folder’s
(guide/usage.rst is in guide.po). false: one catalog per document. A
name: one catalog of that name for every document. |
gettext_location |
Write each message’s locations (#: ../../index.rst:12). Default true. |
gettext_uuid |
Write an identifier per occurrence of a message. Guidedog makes them from the document, the message, and its occurrence, so they are the same in every build. |
gettext_auto_build |
Compile each .po into an .mo beside it, for other tools. Default true.
Guidedog itself reads the .po. |
gettext_additional_targets |
More content to translate: index (index entries), literal-block,
doctest-block, raw, and image (alternative text). |
gettext_allow_fuzzy_translations |
Use fuzzy translations too. Default false. |
gettext_exclude_patterns |
Document-path patterns omitted from POT extraction only, such as ["api/**"].
Default []. The documents remain in HTML and PDF. |
gettext_last_translator, gettext_language_team |
The template header’s Last-Translator and Language-Team. |
figure_language_filename |
The file of an image in the build’s language. Default
"{root}.{language}{ext}": with language = "de", img/logo.png becomes
img/logo.de.png when that file exists. The fields are {root}, {path},
{basename}, {ext}, {docpath}, and {language}. |
translation_progress_classes |
Give translated elements the class translated and the others
untranslated (true), or only one of them ("translated",
"untranslated"), so a stylesheet can show what is left. |
Guidedog’s own words¶
Guidedog writes some words itself: admonition titles, “Added in version 2.1”, “Fig. 1”,
“Contents”, the page layout’s “Previous”, “Next”, “Navigation”, and “Search”, the search
and index pages, and the book’s “Version”. They come from the text domain guidedog,
looked up in this order:
locales/LANGUAGE/LC_MESSAGES/guidedog.poof the project,locales/LANGUAGE/LC_MESSAGES/sphinx.poof the project, as Sphinx reads it,- the catalog built into Guidedog, for German, Spanish, French, Japanese, Brazilian Portuguese, Russian, and Simplified Chinese.
The English words are the message identifiers, and they are Sphinx’s where Sphinx has
the same word, so a project’s sphinx.po keeps working. A project can override any
word, or add a language, with its own guidedog.po.
Templates translate with _(), gettext(), and ngettext(), as Sphinx’s
templates do:
<small>{{ _('Previous') }}</small>
{{ _('Last updated on %s.')|format(last_updated) }}
numfig_format, html_title, and html_short_title follow the language unless
conf.toml sets them.
Dates¶
|today|, the book’s date, and a page’s last_updated are formatted as Sphinx
formats them: today_fmt and html_last_updated_fmt are strftime formats, and
the names of months and days follow language, so %b %d, %Y is “Sep 29, 2026” in
English and “Sept. 29, 2026” in German. An empty format is _('%b %d, %Y'), which a
catalog may translate. The names come from the Unicode CLDR for the languages above;
other languages use English, as Sphinx does for a language Babel does not know.
The date is the local date, in the local time zone. Set SOURCE_DATE_EPOCH (seconds
since 1970, in UTC) to build reproducibly, with the same dates on every machine.