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.
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 thatxgettext
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.
-
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 topo/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.
HTML and JavaScript don't directly support gettext po and mo files. The
translations from po files are converted to a JavaScript function by
po/po2json
which inserts the actual translations into the
po.empty.js template.
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.
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 withmake 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 "master" to the new branch name.