feat: add full Zonemaster stack with Docker and Spanish UI
- Clone all 5 Zonemaster component repos (LDNS, Engine, CLI, Backend, GUI) - Dockerfile.backend: 8-stage multi-stage build LDNS→Engine→CLI→Backend - Dockerfile.gui: Astro static build served via nginx - docker-compose.yml: backend (internal) + frontend (port 5353) - nginx.conf: root redirects to /es/, /api/ proxied to backend - zonemaster-gui/config.ts: defaultLanguage set to 'es' (Spanish) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,482 @@
|
||||
# Translating Engine, CLI and Backend
|
||||
|
||||
|
||||
## Table of contents
|
||||
* [Overview]
|
||||
* [Software preparation]
|
||||
* [GitHub preparation]
|
||||
* [Tools]
|
||||
* [Clone preparation]
|
||||
* [Language Codes]
|
||||
* [Translation steps]
|
||||
* [Updates to msgids]
|
||||
* [Adding a new language]
|
||||
* [Technical details]
|
||||
|
||||
## Overview
|
||||
|
||||
This document has instructions for translation in [PO files] and the
|
||||
[Gettext system]. It is used in Zonemaster-Engine, Zonemaster-CLI and
|
||||
Zonemaster-Backend. Zonemaster-GUI uses a different solution. See the
|
||||
[Zonemaster GUI translation guide] for instructions for that part.
|
||||
|
||||
[PO files] are found in the following directories:
|
||||
* [share][zonemaster-engine share] in Zonemaster-Engine
|
||||
* [share][zonemaster-cli share] in Zonemaster-CLI
|
||||
* [share][zonemaster-backend share] in Zonemaster-Backend
|
||||
|
||||
There is one PO file per language in each component. A PO file consists of
|
||||
multiple entries. An entry consists of three parts. First an optional header
|
||||
(lines starting with "#") which can have the "fuzzy" tag (more below), second
|
||||
the *msgid* which is the untranslated text (in English in the case of Zonemaster)
|
||||
that comes from the program code (Perl code in the case of Zonemaster), and the
|
||||
third part is the *msgstr* which is the translated text. The task of the
|
||||
translator is to create and update *msgstr*.
|
||||
|
||||
In many *msgid* there is one or several arguments within `{...}`, e.g.
|
||||
`{ns_ip_list}`. The same arguments must be found in *msgid* and *msgstr*. The
|
||||
value of the argument will be inserted at run time. The format of that value
|
||||
depends on the argument name, and a specification for arguments used, mainly in
|
||||
Zonemaster-Engine, can be found in [Arguments for test case messages].
|
||||
|
||||
## Software preparation
|
||||
|
||||
For the steps below you need to work on a computer with Git, Perl and Gettext.
|
||||
Select what OS you want to work on from the list below. Other OSs will also work,
|
||||
but you will have to find instructions elsewhere.
|
||||
|
||||
* Rocky Linux
|
||||
|
||||
Install the following:
|
||||
```
|
||||
dnf install git make perl-App-cpanminus perl-Try-Tiny
|
||||
cpanm Locale::PO
|
||||
```
|
||||
|
||||
* Debian
|
||||
|
||||
Install the following:
|
||||
```
|
||||
apt install gettext git liblocale-po-perl
|
||||
```
|
||||
|
||||
* FreeBSD
|
||||
|
||||
Install the following:
|
||||
```
|
||||
pkg install gettext-tools git-lite gmake p5-Locale-PO p5-Try-Tiny
|
||||
```
|
||||
|
||||
* Ubuntu
|
||||
|
||||
Install the following:
|
||||
```
|
||||
apt install gettext git make liblocale-po-perl
|
||||
```
|
||||
|
||||
## GitHub preparation
|
||||
|
||||
For full integration with Zonemaster translation you need a GitHub account
|
||||
and forks of the Zonemaster repositories. If you do not have one you can easily
|
||||
[create an account at GitHub][GitHub signup]. If you are not willing to create
|
||||
one, contact the Zonemaster work group for instructions by sending an email to
|
||||
"zonemaster@zonemaster.net".
|
||||
|
||||
To create the forks of the Zonemaster repositories
|
||||
1. Go to [GitHub] and log in with your account.
|
||||
2. Go to the [Zonemaster-Engine repository].
|
||||
3. Press "Fork" in the top right corner (see "[Forking a repository]").
|
||||
4. Repeat steps 2 and 3 for the the following repositories:
|
||||
* [Zonemaster-CLI repository]
|
||||
* [Zonemaster-Backend repository]
|
||||
|
||||
Make sure that your public *ssh* key is uploaded to GitHub
|
||||
(see "[Adding a new SSH key to your GitHub account]") and that its private key
|
||||
is available on the computer you are going to work from.
|
||||
|
||||
|
||||
## Tools
|
||||
|
||||
The [PO file][PO files] can be edited with a plain text editor, but then it is
|
||||
important to keep the database structure of the file. There are tools that
|
||||
makes editing of the PO files easier. When using those, the PO file is
|
||||
handled as a database instead of as a plain file.
|
||||
|
||||
* There is [Emacs PO-mode], available as a plug-in to the [GNU Emacs] file
|
||||
editor, which makes updating and searching in the ".po" file easier and more
|
||||
robust.
|
||||
* There is also "[GNOME Translation Editor]", a graphical PO editor
|
||||
available for at least Windows and Linux.
|
||||
* There is [POEDIT] in free version that Zonemaster translator has reported to
|
||||
work well.
|
||||
* There are more tools available, either cloud services or programs
|
||||
for download, and they could be found by searching for "po editor".
|
||||
|
||||
|
||||
## Clone preparation
|
||||
|
||||
You need a local clone of the repository to work in (see
|
||||
"[Cloning a repository]"). You need that for all repositories with messages to
|
||||
translate -- Zonemaster-Engine, Zonemaster-CLI and Zonemaster-Backend. (For
|
||||
Zonemaster-GUI see [Zonemaster GUI translation guide].)
|
||||
|
||||
Here it is assumed that the three repositories are cloned from the same
|
||||
directory, i.e. all three clones are sub-directories to the same directory.
|
||||
|
||||
* If you use "old" clones, instead of creating them afresh, then you must do the
|
||||
following (if there is no `develop` branch, checkout `origin/develop` and skip
|
||||
`pull`).
|
||||
|
||||
```
|
||||
git fetch --all
|
||||
git checkout develop
|
||||
git pull
|
||||
```
|
||||
|
||||
* Clone the three repositories:
|
||||
```sh
|
||||
git clone https://github.com/zonemaster/zonemaster-engine
|
||||
git clone https://github.com/zonemaster/zonemaster-cli
|
||||
git clone https://github.com/zonemaster/zonemaster-backend
|
||||
```
|
||||
|
||||
* Check out `origin/develop` branch in the three repositories:
|
||||
```sh
|
||||
git -C zonemaster-engine checkout origin/develop
|
||||
git -C zonemaster-cli checkout origin/develop
|
||||
git -C zonemaster-backend checkout origin/develop
|
||||
```
|
||||
|
||||
You must always start from `develop` branch (or `origin/develop` branch) and any
|
||||
`develop` branch must be even with `origin/develop`.
|
||||
|
||||
Now it is time to connect your own forks created in [GitHub preparation] above
|
||||
to the created clones. We take *Zonemaster-Engine* as an example, but should be
|
||||
repeated for all clones.
|
||||
|
||||
* You have a user name at GitHub. Here we use "xxxx" as your user name and also
|
||||
the name of the remote in clone on the local machine.
|
||||
* Enter the clone:
|
||||
```
|
||||
cd zonemaster-engine
|
||||
```
|
||||
|
||||
* Create the connection to your fork by making it "remote" and synchronize to
|
||||
it:
|
||||
```
|
||||
git remote add xxxx git@github.com:xxxx/zonemaster-engine.git
|
||||
git fetch --all
|
||||
```
|
||||
|
||||
Now you should have updated local clones of all three repositories.
|
||||
|
||||
|
||||
## Language Codes
|
||||
|
||||
Zonemaster uses [ISO 639-1] two-letter language codes, in lower case.
|
||||
Zonemaster-GUI is currently available in the following languages:
|
||||
|
||||
* `da` for Danish language
|
||||
* `en` for English language
|
||||
* `es` for Spanish language
|
||||
* `fi` for Finnish language
|
||||
* `fr` for French language
|
||||
* `nb` for Norwegian language
|
||||
* `sl` for Slovenian language
|
||||
* `sv` for Swedish language
|
||||
|
||||
If a language is added the correct two-letter code must be used.
|
||||
|
||||
In the steps below `xx` represent the language code that you should work with.
|
||||
Replace that with the correct code.
|
||||
|
||||
|
||||
## Translation steps
|
||||
|
||||
The steps in this section will cover most translation work. The steps are the
|
||||
same for all three repositories.
|
||||
|
||||
* Make sure that the working tree is clean. Remove all other files and updates.
|
||||
If you have edited your PO file, then make a copy of it outside the repository.
|
||||
```
|
||||
git clean -dfx
|
||||
git reset --hard
|
||||
```
|
||||
|
||||
* The following command should report that the working tree is clean.
|
||||
```
|
||||
git status --ignored
|
||||
```
|
||||
|
||||
* Check-out the *develop* branch and create a new branch to work in. You can call
|
||||
the new branch whatever you want, but here we use the name
|
||||
"translation-update". If that name is already taken, you have to give it a new
|
||||
name or remove the old branch.
|
||||
```
|
||||
git checkout origin/develop
|
||||
git checkout -b translation-update
|
||||
```
|
||||
|
||||
* Go to the *share* directory. Stay in the *share* directory for the remaining
|
||||
translation steps.
|
||||
```
|
||||
cd share
|
||||
```
|
||||
|
||||
* If you have a partly edited PO file that you want to continue on, then it is
|
||||
time to copy it back into the `share` directory before the next step. Or use
|
||||
the PO file already in the `share` directory.
|
||||
|
||||
* Run the update command for the PO file for the language you are going to work
|
||||
with. Replace "xx" with the language code in question. This will synchronize
|
||||
the PO file with the *msgids* in the Perl code.
|
||||
```
|
||||
./update-po xx.po
|
||||
```
|
||||
|
||||
* The PO file is updated with new *msgids*, if any, and now you can start
|
||||
working with it. Unless this is the first translation you only have to work
|
||||
with updated or untranslated items.
|
||||
|
||||
* Update the PO file with the tool of your choice (see section "[Tools]" above).
|
||||
You can copy the PO file to another computer, edit it there, and then copy it
|
||||
back to your Zonemaster-Engine clone -- or Zonemaster-CLI clone or
|
||||
Zonemaster-Backend clone depending on what repository you do the translation
|
||||
for.
|
||||
|
||||
* When doing the update, do not change the *msgid*, only the *msgstr*. The
|
||||
*msgid* cannot be updated in this process. They are the links between the Perl
|
||||
module and the PO file.
|
||||
|
||||
* If you find a *msgid* that needs an update please see section
|
||||
[Updates to msgids] for how to report it.
|
||||
|
||||
* If there is a `{...}` in the *msgid* then [Arguments for test case messages]
|
||||
will help with the type of data if not obvious.
|
||||
|
||||
* Try to translate as close to the original as possible, but still make sure
|
||||
that the language is sound and valid.
|
||||
|
||||
* Inspect every *fuzzy entry* (tagged with "fuzzy"). Update *msgstr*
|
||||
if needed and remove the "fuzzy" tag. The "fuzzy" tag must always be removed.
|
||||
|
||||
* 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, especially of the *msgid*
|
||||
has been changed.
|
||||
|
||||
* Any remaining *obsolete entries* (lines at the end of the file starting
|
||||
with "#~") could be removed. They serve no purpose anymore.
|
||||
|
||||
* With the following command, check that the messages arguments (`{...}`) in all
|
||||
*msgstr* strings match up with those in the *msgid* strings.
|
||||
```
|
||||
../../zonemaster-engine/util/check-msg-args xx.po
|
||||
```
|
||||
|
||||
* When the update of all *msgstr* is complete run the `tidy-po` command to
|
||||
create a consistent formatting of the PO file. Do this again if you do
|
||||
further updates.
|
||||
|
||||
```
|
||||
make POFILES=xx.po tidy-po
|
||||
```
|
||||
|
||||
* You can check all updates that have been done to the xx.po file. That includes
|
||||
both updates done by the update command and your updates.
|
||||
```
|
||||
git diff xx.po
|
||||
```
|
||||
|
||||
* When the update is completed, it is time to commit the changes. You should
|
||||
only commit the "xx.po" file.
|
||||
```
|
||||
git commit -m 'Write a description of the change' xx.po
|
||||
```
|
||||
|
||||
* There could be other files changed or added that should not be included.
|
||||
Run the status command to see them.
|
||||
```
|
||||
git status
|
||||
```
|
||||
|
||||
* Other changed files could be reset by a `git checkout`. This could also
|
||||
be done before creating the commit.
|
||||
```
|
||||
git checkout FILENAME
|
||||
```
|
||||
|
||||
* Files that were created but are not needed can just be removed. This could also
|
||||
be done before the commit.
|
||||
```
|
||||
rm FILENAME
|
||||
```
|
||||
|
||||
* Now push the local branch you created to your fork at GitHub.
|
||||
"translation-update" is name of the branch you created above and
|
||||
have committed the updates to. Use your GitHub user name instead of
|
||||
"xxxx".
|
||||
```
|
||||
git push -u xxxx translation-update
|
||||
```
|
||||
|
||||
* Go to your fork collection at GitHub, https://github.com/xxxx/ using your
|
||||
GitHub user name instead of "xxxx". There you can select the fork for this
|
||||
translation.
|
||||
|
||||
* Select to create a new pull request. Here we use Zonemaster-Engine as an
|
||||
example.
|
||||
* The base repository should be *zonemaster/zonemaster-engine*.
|
||||
* The base branch should be *develop* (not *master*).
|
||||
* The "head" should be your fork.
|
||||
* The "compare" should be the same branch as you created above and pushed to
|
||||
your fork, e.g. "translation-update".
|
||||
|
||||
* 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.
|
||||
|
||||
* If you by mistake have not started with an updated version of the develop
|
||||
branch you can get extra files listed.
|
||||
|
||||
* If you want to correct something now before the pull request has been created,
|
||||
do that in your local clone and do a new commit and push that to your fork.
|
||||
|
||||
* Press "create pull request", write a nice description and press "create"
|
||||
again.
|
||||
|
||||
* If you go back to your own computer and just keep 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. Or keep them for next time.
|
||||
|
||||
|
||||
## Updates to msgids
|
||||
|
||||
The *msgid* cannot be updated in the translation process. If you find an *msgid*
|
||||
that needs an update you can provide that information to the project. The
|
||||
preferred way is to create an issue in the relevant repository.
|
||||
|
||||
* Message *(msgid)* in Zonemaster-Engine: [issue][new issue zonemaster-engine]
|
||||
* Message *(msgid)* in Zonemaster-CLI: [issue][new issue zonemaster-cli]
|
||||
* Message *(msgid)* in Zonemaster-Backend: [issue][new issue zonemaster-backend]
|
||||
|
||||
If the message is in Zonemaster-Engine then include the message tag found in the
|
||||
header, e.g. "BASIC:NO_PARENT", in the issue description. Also include the *msgid*
|
||||
as it is now and a suggestion for new wording.
|
||||
|
||||
|
||||
## Adding a new language
|
||||
|
||||
If you want to add a new language, then follow steps in section
|
||||
"[Translation steps]" above with some modifications. Before you add a language
|
||||
contact the Zonemaster project to discuss timeplan and other aspects of the new
|
||||
language. Every language should be updated at every new release of Zonemaster if
|
||||
there are updated or added messages to be translated.
|
||||
|
||||
* First, as in the translation steps, create the branch to work in.
|
||||
```
|
||||
git checkout origin/develop
|
||||
git checkout -b translation-update
|
||||
```
|
||||
|
||||
There is no PO file for new language, and it has to be created. The easiest way
|
||||
is to make a copy of an existing file.
|
||||
|
||||
* Determine what language code to use for the new language (also see section
|
||||
"[Language Codes]").
|
||||
|
||||
* It must be a code that is available in the *locale* system in the OSs that
|
||||
Zonemaster supports. Try the following commands to see if it is available.
|
||||
Replace "xx" with that code that you think it should be. Consult with
|
||||
Zonemaster Project if in doubt.
|
||||
```
|
||||
locale -a | grep xx_ # Works in FreeBSD and Rocky Linux
|
||||
grep xx_ /etc/locale.gen # Works in Debian and Ubuntu
|
||||
```
|
||||
|
||||
* Go to the *share* directory and create a new blank PO file. Then "add" it
|
||||
to `git` before working on it.
|
||||
```
|
||||
cd share
|
||||
make POLANG=xx new-po
|
||||
git add xx.po
|
||||
```
|
||||
|
||||
* Verify and update the file header if needed.
|
||||
|
||||
* Now you go back to section "[Translation steps]" and continue in the same way
|
||||
as with an existing language.
|
||||
|
||||
|
||||
## Technical details
|
||||
|
||||
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`.
|
||||
|
||||
The translated strings are maintained in files named "<LANG-CODE>.po". You will
|
||||
find the current PO files in the "share" directories listed in the "[Overview]"
|
||||
section (also see section "[Language Codes]").
|
||||
|
||||
The command `./update-po` will update the PO file with new message ids (*msgid*)
|
||||
from the source code. Execute `./update-po xx.po` to update the PO file for
|
||||
language "xx". This should only be strictly necessary to do when a module has
|
||||
been added, changed or removed, but it it recommended to do this step every time.
|
||||
|
||||
Execute `make update-po` to update all the PO files with new message ids from the
|
||||
source code.
|
||||
|
||||
By default the updated PO file will suggested 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 one of the following
|
||||
commands instead:
|
||||
```
|
||||
make update-po MSGMERGE_OPTS=--no-fuzzy-matching POFILES=xx.po
|
||||
make update-po MSGMERGE_OPTS=--no-fuzzy-matching
|
||||
```
|
||||
|
||||
|
||||
<!-- Zonemaster links point on purpose on the develop branch. -->
|
||||
[Adding a new SSH key to your GitHub account]: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account
|
||||
[Adding a new language]: #adding-a-new-language
|
||||
[Arguments for test case messages]: ../../public/specifications/tests/ArgumentsForTestCaseMessages.md
|
||||
[Clone preparation]: #clone-preparation
|
||||
[Cloning a repository]: https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository#cloning-a-repository
|
||||
[Emacs PO-mode]: https://www.gnu.org/software/gettext/manual/html_node/PO-Mode.html#PO-Mode
|
||||
[Forking a repository]: https://docs.github.com/en/get-started/quickstart/fork-a-repo#forking-a-repository
|
||||
[GNOME Translation Editor]: https://wiki.gnome.org/Apps/Gtranslator
|
||||
[GNU Emacs]: https://www.gnu.org/software/emacs/
|
||||
[Gettext system]: https://www.gnu.org/software/gettext/
|
||||
[GitHub preparation]: #github-preparation
|
||||
[GitHub signup]: https://github.com/signup
|
||||
[GitHub]: https://github.com/
|
||||
[ISO 639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||
[Language Codes]: #language-codes
|
||||
[New issue zonemaster-backend]: https://github.com/zonemaster/zonemaster-backend/issues/new
|
||||
[New issue zonemaster-cli]: https://github.com/zonemaster/zonemaster-cli/issues/new
|
||||
[New issue zonemaster-engine]: https://github.com/zonemaster/zonemaster-engine/issues/new
|
||||
[Overview]: #overview
|
||||
[PO files]: https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
|
||||
[POEDIT]: https://poedit.net/
|
||||
[Software preparation]: #software-preparation
|
||||
[Technical details]: #technical-details
|
||||
[Tools]: #tools
|
||||
[Translation steps]: #translation-steps
|
||||
[Translation]: https://github.com/zonemaster/zonemaster-engine/blob/develop/docs/Translation.pod
|
||||
[Updates to msgids]: #updates-to-msgids
|
||||
[Zonemaster GUI translation guide]: https://github.com/zonemaster/zonemaster-gui/blob/develop/docs/TranslationGuide.md
|
||||
[Zonemaster-Backend repository]: https://github.com/zonemaster/zonemaster-backend
|
||||
[Zonemaster-CLI repository]: https://github.com/zonemaster/zonemaster-cli
|
||||
[Zonemaster-Engine repository]: https://github.com/zonemaster/zonemaster-engine
|
||||
[Zonemaster-backend share]: https://github.com/zonemaster/zonemaster-backend/tree/develop/share
|
||||
[Zonemaster-cli share]: https://github.com/zonemaster/zonemaster-cli/tree/develop/share
|
||||
[Zonemaster-engine share]: https://github.com/zonemaster/zonemaster-engine/tree/develop/share
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user