Cockpit Internationalization============================All human-visible strings on Cockpit's web pages should be translatable. Thisdocument describes the entire internationalization process, which uses [GNU gettext](https://www.gnu.org/software/gettext/) and related tools as much as possible.Marking strings---------------Strings that are visible to humans and which should be translated must bemarked 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 withthe `translate="yes"` attribute. Example:```html<span translate="yes">Image</span>```* If the string appears in JavaScript source, it must use the[cockpit.gettext()](https://docs.cockpit-project.org/cockpit-guide/latest/guide/cockpit-locale.html#cockpit-locale-gettext)or a related function, commonly called through an alias `_()`, with double-quotedstrings so that `xgettext` can recognize it. Example:```jsconst _ = 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()](https://docs.cockpit-project.org/cockpit-guide/latest/guide/cockpit-locale.html#cockpit-locale-ngettext)instead:```jsvar translated = cockpit.ngettext("This thing", "The things", numberOfThings);```The [cockpit.format()](https://docs.cockpit-project.org/cockpit-guide/latest/guide/cockpit-util.html#cockpit-format)function is useful for parameterized strings where the order of parametersmight change between languages.Translation process-------------------* Translatable strings from HTML, JavaScript (as above) and C files getextracted with various invocations of[xgettext](https://linux.die.net/man/1/xgettext), see[po/Makefile.am](https://github.com/cockpit-project/cockpit/blob/main/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](https://translate.stg.fedoraproject.org/projects/cockpit/)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](https://github.com/cockpit-project/cockpit/blob/main/bots/po-refresh)which is invoked regularly by[bots/po-trigger](https://github.com/cockpit-project/cockpit/blob/main/bots/po-trigger).* Translations can also be done using any other tool or platform and besubmitted via pull requests that update the `po/XX.po` files. In this casethey should then also be uploaded to Weblate either manually using Weblate UIor by pushing these files into [cockpit-weblate](https://github.com/cockpit-project/cockpit-weblate)repository.Using translations at runtime-----------------------------HTML and JavaScript don't directly support gettext po and mo files. Thetranslations from po files are converted to a JavaScript function by[cockpit-po-plugin](../pkg/lib/cockpit-po-plugin.js)which inserts the actual translations into a[cockpit.locale()](https://docs.cockpit-project.org/cockpit-guide/latest/guide/cockpit-locale.html#cockpit-locale-locale) call.The resulting files are written to `dist/<page>/po.XX.js` from where theycan be imported by the page and used by `cockpit.gettext()`.HTML pages which use `translate="yes"` tags need to call[cockpit.translate()](https://docs.cockpit-project.org/cockpit-guide/latest/guide/cockpit-locale.html#cockpit-locale-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 RHELrelease. Run these steps to initialize translations for it:* In [cockpit-weblate](https://github.com/cockpit-project/cockpit-weblate) create a new branchwith 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](https://translate.stg.fedoraproject.org/projects/cockpit/),click the "Add new translation component" button and create a new component. Give it a namethat matches the new branch. Point it to [cockpit-weblate](https://github.com/cockpit-project/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](https://github.com/cockpit-project/cockpit/blob/main/po/Makefile.am)from "main" to the new branch name.