translations setup
Translations of darktable’s documentation are maintained via Weblate.
🔗Overview of the setup and flow of information for translations using Weblate
In short:
- The docs are primarily maintained in English in the .md files present in
content/*.md. - From there a POT file (
po/content.pot) of all translatable strings is maintained. - Weblate maintains each language’s individual PO files (
po/content.{lang}.po) which contain the translated strings. - Upon deployment of the docs, language-specific .md-files are generated using
generate-translations.shwhich hugo then renders to .html files and the EPUB and PDF variants.
🔗GitHub to Weblate: source string synchronisation
- The original English files (
content/*.md) are changed through a pull request on GitHub (see workflow). - A nightly GitHub action updates the POT file (
po/content.pot) housing all translatable strings withgenerate-translations.sh --no-translations. Note: The script updates POT and PO files but we don’t commit the updated PO files to the repository as in our setup the PO files are entirely managed by Weblate to avoid merge conflicts. - Weblate automatically pulls the updated POT file (triggered by the Weblate GitHub app) and internally populates the PO file of each translated language with new/updated strings
- Weblate commits the changes to GitHub by opening a pull request.
- The pull request gets merged after review.
🔗Weblate to GitHub: translation synchronisation
- Translations happen on Weblate. See translators guide for a guide on how to translate.
- Weblate internally updates each language’s PO file and commits them to GitHub via pull request. To keep the number of pull requests at bay this happens in batches.
🔗Deployment of translations
Upon deployment at docs.darktable.org translated .md-files are generated from the PO files in /po/ using generate-translations.sh --no-update. This step is disabled for the auto-build GitHub Pages.
🔗Adding a new language
- Add a new language to Weblate. See Weblate’s documentation for how to do this. Make sure the newly created PO file is committed to the dtdocs repository.
- In the files
config.yaml,config-pdf.yamlandconfig-epub.yaml, locate thelanguages:line. - Add the language you wish to translate. For example, the English entry looks like this:
en-us: title: darktable user manual weight: 1
🔗Enabling and disabling languages
Languages are controlled by two independent systems that must be manually kept in sync:
config.yamlandconfig-pdf.yaml— hugo’s configuration. Languages listed here get their own section of the built website or PDF.disable-languages— A space-separated list of language codes in the repository’s base directory.generate-translations.shreads this file and skips generating.{lang}.mdfiles for any language listed here, regardless of whether a PO file exists for it.
The language switcher in the theme only lists a language when translated .{lang}.md files exist for the current page — it uses Hugo’s .IsTranslated and .Translations variables, which reflect actual files on disk, not config.yaml entries. A language present in config.yaml but listed in disable-languages will therefore not appear in the switcher, as no translated files are generated for it. Its config.yaml entry is dormant until it is removed from disable-languages.
To enable a language, it should be present in config.yaml, config-pdf.yaml and config-epub.yaml and absent from disable-languages.
To disable a language, it should be listed in disable-languages. The config.yaml, config-pdf.yaml and config-epub.yaml entries can remain in place for when the language is re-enabled.
🔗Translating theme strings for website, EPUB, and PDF
There are three themes for the darktable documentation: one for the HTML website, one for EPUB, and one for the PDF. Each has a small set of UI strings (e.g. “Table of Contents”, “Copyright”, “Search”) that must be translated manually — these strings are not managed by Weblate.
- Go to
themes/hugo-darktable-docs-theme/i18n. - Copy the file
en-us.yamland name the new file after your language using a locale code with a dash (e.g.de-de.yaml,fr-fr.yaml). - Translate the strings in the new yaml file.
- Check the translated yaml file into git, push it to GitHub, and open a pull request to have your changes accepted.
- Repeat for
themes/hugo-darktable-docs-epub-theme/i18nandthemes/hugo-darktable-docs-pdf-theme/i18n. These themes use shorter locale codes, using only the language code (e.g.de.yaml) or an underscore for regional variants (e.g.pt_br.yaml).
🔗generate-translations.sh
This script is used by the nightly GitHub action and can also be run locally by maintainers who need to update translations manually or debug the build.
The script is a wrapper around po4a to orchestrate the interplay between the original .md files and the translations. The script reads the disable-languages file in the repository’s base directory, filters out disabled languages, builds a temporary po4a config file containing all content/**/*.md files, and then calls po4a $1 --verbose $po4a_conf — the flag is passed through directly to po4a.
It requires one of the three arguments.
--no-translations- Generates POT and PO files (
po/content.potandpo/content.{lang}.po) from the source .md files (content/*.md). Does not produce any translated output files. New or changed strings from the source files are pulled into the POT/PO files, but no*.{lang}.mdfiles are created. This is used after updates to the English source files to prepare the POT and PO files for Weblate. --no-update- Generates the translated Markdown files from the existing PO files, without updating the POT/PO files. This means the source files (
content/*.md) are not re-read; existing translations are rendered directly into localized.{lang}.mdfiles. --rm-translations- Removes the generated translated files.
po4adeletes the localized*.{lang}.mdoutput files previously created by--no-update. The PO/POT files are left untouched.