TRANSLATION

Introduction

The translation system in Zonemaster is a two-step process, where internal message tags are first replaced by English strings with argument placeholders, and a second step where GNU gettext is used to translate the strings to other languages and fill in the placeholders based on provided data.

All translation files live in the share directory in the Zonemaster::Engine source directory and all commands described here are executed from that directory.

For developers of Zonemaster test modules

The test module code should produce log messages with message tags, as documented elsewhere. These tags will be used for translation to human language, for determining the severity of the event logged and to make the events easily used by other software.

Each test module must also have a method named tag_descriptions(). This method must return a reference to a hash whose entries are expected to look like this, where MESSAGE_TAG is a message, TEST_MODULE is the name of a test module tag and "Hello, {name}!" is a message id:

MESSAGE_TAG => sub {
    __x    # TEST_MODULE:MESSAGE_TAG
      "Hello, {name}!", @_;
},

A number of things are important here. Keys in the hashref are message tags and values are coderefs. The coderef calls Locale::TextDomain::__x() with a Perl brace format string (a.k.a. message id) and passes along its own @_). The coderef propagates the return value of Locale::TextDomain::__x(). The line immediately before the format string contains a comment consisting of the module name, a colon and the message tag.

The format strings themselves, the comments and the line numbers of the __x calls are used by the gettext tooling when updating the PO files with new message ids and old message strings.

Every time you add, remove or modify a tag or its message id, re-run make update-po as descibed in the next section. Make sure the message tag comments are properly added and up to date.

For translators

Software preparation

For the steps below you need to work on a computer with Git, Perl and Xgettext. Select what OS you want to work on. Other OSs will also work, but you will have to find instructions elsewhere.

FreeBSD

Install the following:

pkg install git-lite devel/p5-Locale-XGettext devel/p5-Locale-Msgfmt devel/gmake

CentOS

To be written.

Ubuntu

To be written.

Debian

To be written

Background

The first step in updating the translations is to generate a new template file (Zonemaster-Engine.pot). In practice you rarely need to think about generating it as it is generally performed as an implicit intermediate step. If you do want to generate it, the command is make extract-pot (gmake extract-pot on FreeBSD).

The translated strings are maintained in files named {language_code}.po (currently en.po, sv.po, da.po or fr.po). Execute make update-po (gmake update-po on FreeBSD) to update these files with new message ids from the source code (make extract-pot will be infoked behind the scenes). This should only be necessary to do when a developer has added or changed a test module.

By default make update-po suggests translations for new message ids based on fuzzy matching of similar strings. This is not always desirable and you can disable fuzzy matching by executing make update-po MSGMERGE_OPTS=--no-fuzzy-mathing instead.

Github preparation

For full integration with Zonemaster translation you need a Github account and a fork of Zonemaster-Engine. If you do not have a Github account you can easily create one at https://github.com/. If you are not prepared to create one, contact the Zonemaster work group for instructions, either by creating an issue in https://github.com/zonemaster/zonemaster-engine/issues or by sending an email to mailto:contact@zonemaster.net.

To create a fork of Zonemaster-Engine go to https://github.com/zonemaster/zonemaster-engine, make sure you are logged in at Github and press the "Fork" button.

Make sure you have your public ssh key uploaded to Github and its private key available on the computer you are going to work from.

Tools

The ".po" can be edited with a plain text editor, but then it is important to keep the database structur of the file. There are tools that makes editing of the ".po" files easier. When using those, the ".po" file is handled rather as a database then a plain file.

Steps

For normal translation work, follow the steps below.

  • Clone the Zonemaster-Engine repository with git clone https://github.com/zonemaster/zonemaster-engine.git and enter the direcory created, cd zonemaster-engine.

  • Check-out the develop branch and create a new branch to work in, git checkout origin/develop; git checkout -b translation-update

  • Now it is time to add your own fork of Zonemaster-Engine to the created clone. Run git remote add XXXXX git@github.com:XXXXX/zonemaster-engine.git where XXXXX is your Github user name.

  • Go to the share directory with cd share and execute make update-po (gmake update-po on FreeBSD).

  • Update the po file the language to be updated. The en.po file should not be updated in this way. Instead, create an issue or a pull request to have the message updated in the Perl module.

  • When doing the update, do not change the msgid, only update msgstr. Instead, create an issue or a pull request to have the message updated in the Perl module.

  • Inspect every fuzzy entry (tagged with "fuzzy"). Update msgstr if needed and remove the "fuzzy" tag.

  • Search for untranslated entries (empty msgstr) and add a translation. At the end of the file there could be obsolete entries (lines starting with "#~") and those could have matching translations.

  • Any remaining obsolete entries (lines at the end of the file starting with "#~") could be removed.

  • When the update is completed, it is time to commit the changes. First do a git add xx.po where xx is the language code of the po file you have updated. Make sure not to "add" any other file that might have been changed.

  • Run git status to verify that only the ".po" file as been added for commit.

  • Create a commit, git commit -m 'Write a description of the change'.

  • Other changed files could be reset by git checkout FILE-NAME.

  • Added files not needed can just be removed by rm FILE-NAME.

  • Now push the branch to your fork at Github. Run git push -u XXXXX translation-update where XXXXX is your Github user name and "translation-update" is name of the branch you created above and have been working on.

  • Go to your fork at Github, https://github.com/XXXXX/zonemaster-engine where XXXXX is your Github user name.

  • Select to create a new pull request where the base directory should be zonemaster-engine and the base should be develop (not "master"). The "head" should be your fork and "compare" the same branch as you created above and pushed to your fork.

  • Inspect what Github says that will change by the pull request. It should only be the po file that you have updated and nothing else. If additional files are listed, please correct or request for help.

  • Press "create pull request", write a nice description and press "create" again.

  • If you go back to your own computer and just save the clone as it is, you can easily update the pull request if needed with more changes to the same po file. When the pull request has been merged by the Zonemaster work group, you can delete the local clone and on your Github fork you can remove the branch.

For Zonemaster package maintainers

In order to make a new translation usable, it must be compiled to mo format and installed. The first step needs the msgfmt program from the GNU gettext package to be installed and available in the shell path. As long as it is, it should be enough to go to the share directory and run make (gmake on FreeBSD). This is automatically done when following the release instructions.

For the new translation to actually be installed, the mo file must be added to the MANIFEST file. At the end of the make run, it should have printed a list of all the paths that has to be there. Just open MANIFEST in a text editor, check that all the lines are in there and add any that are missing (if you just added a new translation, that will be missing, for example).

Once the new translation is compiled and added to MANIFEST, the normal Perl make install process will install it.