mirror-cockpit-project-cockpit/doc/i18n.md
Freya Gustavsson b1433d5e8c doc: Fix links for Antora
Several files, including the deployment guide index page, link to the
old AsciiDoc guide on our website whereas our new docs site is published
under docs subdomain using Antora. While these links will work in the
future thanks to redirects we should update the links where we can to
avoid this unnecessary redirect.

Other changes include changing links from being header anchors within a
single-page to a multi-page navigation with asciidoctor's xref. This
change only applies to links within the same module and doesn't change
any links from guide to manpage for example. That will be tackled in a
future commit as it also has to deal with compiling to manpages.

Signed-off-by: Freya Gustavsson <freya@venefilyn.se>
2026-07-14 15:47:27 +02:00

4.7 KiB

Cockpit Internationalization

All human-visible strings on Cockpit's web pages should be translatable. This document describes the entire internationalization process, which uses GNU gettext and related tools as much as possible.

Marking strings

Strings that are visible to humans and which should be translated must be marked as such on Cockpit pages, in one of two ways:

  • If the string appears in a HTML source, it must be enclosed in a tag with the translate="yes" attribute. Example:

    <span translate="yes">Image</span>
    
  • If the string appears in JavaScript source, it must use the cockpit.gettext() or a related function, commonly called through an alias _(), with double-quoted strings so that xgettext can recognize it. Example:

    const _ = cockpit.gettext;
    
    var translated = _("Time");
    
    // in a JSX block:
    <tr>
      <th>{ _("Image") }</th>
    </tr>
    

    For strings that involve numbers you need to use cockpit.ngettext() instead:

    var translated = cockpit.ngettext("This thing", "The things", numberOfThings);
    

    The cockpit.format() function is useful for parameterized strings where the order of parameters might change between languages.

Translation process

  • Translatable strings from HTML, JavaScript (as above) and C files get extracted with various invocations of xgettext, see po/Makefile.am. Running make po/cockpit.pot will generate a standard PO template.

  • With make upload-pot the PO template gets uploaded to the Weblate translation platform where everybody can contribute translations to various languages.

  • With make download-po Weblate's translations are downloaded to po/XX.po. This is done by bots/po-refresh which is invoked regularly by bots/po-trigger.

  • Translations can also be done using any other tool or platform and be submitted via pull requests that update the po/XX.po files. In this case they should then also be uploaded to Weblate either manually using Weblate UI or by pushing these files into cockpit-weblate repository.

Using translations at runtime

HTML and JavaScript don't directly support gettext po and mo files. The translations from po files are converted to a JavaScript function by cockpit-po-plugin which inserts the actual translations into a cockpit.locale() call. The resulting files are written to dist/<page>/po.XX.js from where they can be imported by the page and used by cockpit.gettext().

HTML pages which use translate="yes" tags need to call cockpit.translate() which will iterate over all such tags and replace their content with the result of calling cockpit.gettext() on their original content.

Opening a new branch

Occasionally we create a new upstream branch for e. g. a new stable RHEL release. Run these steps to initialize translations for it:

  • In cockpit-weblate create a new branch with the same name. Upload there cockpit.pot that you generated from the new upstream branch with make po/cockpit.pot. If you have also .po files, you can also add them into this branch.

  • On the Weblate Cockpit project page, click the "Add new translation component" button and create a new component. Give it a name that matches the new branch. Point it to cockpit-weblate repository to a branch you created in the previous step.

  • On the new cockpit branch, change WEBLATE_REPO_BRANCH in po/Makefile.am from "main" to the new branch name.