Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/build_ci_img.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ on:
branches:
- main
- staging
- development
- develop
paths:
# Workflow is triggered only if deps change
- "src/backend/pyproject.toml"
- "src/backend/Dockerfile"
- "pyproject.toml"
- "scripts/docker/Dockerfile"
# Allow manual trigger
workflow_dispatch:

Expand All @@ -20,6 +20,7 @@ jobs:
with:
context: .
build_target: ci
dockerfile: scripts/docker/Dockerfile
image_tags: |
"ghcr.io/${{ github.repository }}/backend:ci-${{ github.ref_name }}"

Expand Down
101 changes: 76 additions & 25 deletions docs/developers/translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,11 @@ support translations through the Transifex website.

## Developers

For developers, Transifex offers a [CLI
client](https://docs.transifex.com/client/introduction/) and the
Tasking Manager offers commands to interact with it. The client is
already included in `requirements.txt` so you should have the
Transifex commands installed once you have set up your backend side
code.
For developers, Tasking Manager uses [Transifex](https://www.transifex.com/) to manage UI translations, and the integration is handled using the [Transifex CLI](https://developers.transifex.com/docs/cli).

The Tasking Manager is using Angular Translate to display the
translated strings. It works with key/value pairs in .json format,
which is also the format used to store the translations in Transifex.
Translations are stored in `.json` format as key/value pairs under `frontend/src/locales/`.These files follow the React-based i18n format and are synchronized with Transifex using the CLI.

### Setting up Transifex locally
### Setting up Transifex CLI

To [set up the Transifex
client](https://developers.transifex.com/docs/cli), you'll need a
Expand All @@ -31,25 +24,73 @@ Transifex username/password.
The .tx folder contains the Transifex config file. This is where you
can find the mappings to local translation files.

#### Running the Transifex CLI

You can run the CLI via Docker (recommended) or install it natively. Use one of the following methods:

##### Option 1: Docker-based CLI (Recommended)

Use the provided helper scripts to run the CLI inside Docker:

- **macOS/Linux:**

```bash
./scripts/transifex/tx-docker.sh pull # Downloads the latest translations
./scripts/transifex/tx-docker.sh push -s # Pushes updated source strings (English in our case)
```

- **Windows (PowerShell):**

```bash
./scripts/transifex/tx-docker.ps1 pull
./scripts/transifex/tx-docker.ps1 push -s
```

These scripts will:

- Run Transifex CLI inside a Docker container

- Mount your project directory

- Handle system certificates for secure API communication

If you run into certificate-related errors, update the paths in the script or try the manual install method.

##### Option 2: Manual (Native CLI)

- **Install CLI (macOS/Linux):**

```bash
curl -sSL https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash
```

- **Install CLI (Windows):**
Download from [Transifex CLI Releases](https://github.com/transifex/cli/releases)
Then run:
```bash
tx pull
tx push
```

### Update translation strings

* ```yarn build-locales``` - Execute that command in the `frontend`
- `yarn build-locales` - Execute that command in the `frontend`
folder to get the new translatable strings from all the
`messages.js` files in the frontend code. The changes in the strings
will be pushed to `frontend/src/locales/en.json` file. The ideal is
to execute that command before every pull request that change
something in the translatable strings.
* After the pull request is merged to the `develop` branch, the
- After the pull request is merged to the `develop` branch, the
command `tx push -s` needs to be executed in order to push the
changes to Transifex. The translators receive a notification every
time we push changes to Transifex.

### Update with latest translations

* Before a release, new translations need to be pulled in: ```tx pull
-af --mode translator``` - Gets all translations from Transifex and
- Before a release, new translations need to be pulled in: `tx pull
-af --mode translator` - Gets all translations from Transifex and
puts them into `frontend/src/locales/`.
* The [Transifex
- The [Transifex
dashboard](https://www.transifex.com/hotosm/tasking-manager/dashboard/)
can be used to check the status of the translations. If a language
is not enabled in the `.tx/config` file, the translation updates
Expand All @@ -60,21 +101,31 @@ can find the mappings to local translation files.
The steps required to add a new language support to Tasking Manager
are the following:

* Add the language support using the [Transifex
- Add the language support using the [Transifex
dashboard](https://www.transifex.com/hotosm/tasking-manager/dashboard/);
* Edit `.tx/config` and add a line like: `trans.ml = frontend/src/locales/ml.json`
* Add the new language and language code to:
* The `SUPPORTED_LANGUAGES` dictionary in the config file `backend/config.py`;
* The `supportedLocales` array on `frontend/src/utils/internationalization.js`;
* The polyfills in `frontend/src/utils/polyfill.js`;
* If the new language is not yet supported by
- Edit `.tx/config` and add a line like: `trans.ml = frontend/src/locales/ml.json`
- Add the new language and language code to:
- The `SUPPORTED_LANGUAGES` dictionary in the config file `backend/config.py`;
- The `supportedLocales` array on `frontend/src/utils/internationalization.js`;
- The polyfills in `frontend/src/utils/polyfill.js`;
- If the new language is not yet supported by
[iso-countries-languages](https://github.com/hotosm/iso-countries-languages),
we need to update it and publish a new version.

### Pushing translations

You can also translate locally and push the
Use Transifex's ```tx push -s``` to push local changes to Transifex.
Use Transifex's `tx push -s` (if you are using native CLI method) to push local changes to Transifex.

- Argument `-s` pushes source files (English in our case)
- Argument `-t` pushes all translation files

### Helpful Links

[Transifex CLI Docs](https://developers.transifex.com/docs/cli)

[Tasking Manager Transifex Dashboard](https://www.transifex.com/hotosm/tasking-manager/dashboard/)

[Transifex CLI GitHub](https://github.com/transifex/cli)

* Argument ```-s``` pushes source files (English in our case)
* Argument ```-t``` pushes all translation files
[iso-countries-languages](https://github.com/hotosm/iso-countries-languages)
24 changes: 24 additions & 0 deletions frontend/src/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"banner.button.agree": "",
"banner.privacyPolicy": "",
"banner.text": "",
"banner.button.close": "",
"banner.button.learnmore": "",
"banner.title.notification": "",
"banner.text.archivalNotification": "",
"comment.input.imageUpload.error": "",
"comment.input.imageUpload.progress": "",
"comment.input.sending.progress": "",
Expand Down Expand Up @@ -55,6 +59,7 @@
"header.nav.projects": "",
"header.nav.learn": "",
"header.nav.aboutLink": "",
"header.nav.support": "",
"header.nav.my_contributions": "",
"header.nav.manage": "",
"header.buttons.logIn": "",
Expand Down Expand Up @@ -406,6 +411,8 @@
"projects.formInputs.random_task_selection": "",
"projects.formInputs.random_task_selection.mapping": "",
"projects.formInputs.random_task_selection.description": "",
"projects.formInputs.rapid_power_user": "",
"projects.formInputs.rapid_power_user.description": "",
"projects.formInputs.imagery": "",
"projects.formInputs.imagery.note": "",
"projects.formInputs.priority_areas.options.polygon": "",
Expand Down Expand Up @@ -531,12 +538,25 @@
"project.stats.totalEdits": "",
"project.stats.changesets": "",
"project.stats.edits": "",
"project.stats.edits.info": "",
"project.tasks.unsaved_map_changes.title": "",
"project.tasks.unsaved_map_changes.split": "",
"project.tasks.unsaved_map_changes.unlock": "",
"project.tasks.unsaved_map_changes.actions.close_modal": "",
"project.tasks.no_mapped_tasks_selected": "",
"project.tasks.no_mapped_tasks_selected.description": "",
"project.tasks.invalid_task_state_errortitle": "",
"project.tasks.invalid_task_state_error.description": "",
"project.tasks.user_not_allowed_error.title": "",
"project.tasks.user_not_allowed_error.description": "",
"project.tasks.project_not_published_error.title": "",
"project.tasks.project_not_published_error.description": "",
"project.tasks.task_not_owned_error.title": "",
"project.tasks.task_not_owned_error.description": "",
"project.tasks.not_ready_for_validation_error.title": "",
"project.tasks.not_ready_for_validation_error.description": "",
"project.tasks.cannot_validate_mapped_task_error.title": "",
"project.tasks.cannot_validate_mapped_task_error.description": "",
"project.tasks.josm_error": "",
"project.tasks.josm_error.description": "",
"project.tasks.lock_error.generic": "",
Expand Down Expand Up @@ -988,6 +1008,8 @@
"pages.learn.tutorials.tm_manual.description": "",
"pages.learn.tutorials.osm_step_by_step.title": "",
"pages.learn.tutorials.osm_step_by_step.description": "",
"pages.learn.tutorials.cheatsheet.title": "",
"pages.learn.tutorials.cheatsheet.description": "",
"pages.learn.tutorials.learnosm.title": "",
"pages.learn.tutorials.learnosm.description": "",
"pages.learn.map.steps.project.title": "",
Expand Down Expand Up @@ -1024,6 +1046,8 @@
"pages.learn.manage.description": "",
"pages.learn.manage.steps.join.title": "",
"pages.learn.manage.steps.join.description": "",
"pages.learn.manage.list": "",
"pages.learn.manage.form": "",
"pages.learn.manage.steps.create.title": "",
"pages.learn.manage.steps.create.description": "",
"pages.learn.manage.steps.data.title": "",
Expand Down
26 changes: 25 additions & 1 deletion frontend/src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"banner.button.agree": "Souhlasím",
"banner.privacyPolicy": "Zásady ochrany osobních údajů",
"banner.text": "Používáme cookies a podobné technologie k rozpoznání a analýze vašich návštěv a měření míry využití a aktivity provozu. Informace o tom, jak používáme údaje o vaší návštěvě, nebo informace, které nám poskytnete, se dozvíte na našem {link}. Kliknutím na „Souhlasím“ souhlasíte s používáním cookies.",
"banner.button.close": "Zavřít",
"banner.button.learnmore": "Zjistit více",
"banner.title.notification": "Důležité upozornění pro uživatele",
"banner.text.archivalNotification": "Pozor: v rámci průběžné údržby Tasking Manageru budou projekty vytvořené před rokem 2020 archivovány.",
"comment.input.imageUpload.error": "Nahrávání obrázku se nezdařilo.",
"comment.input.imageUpload.progress": "Nahrávání souboru ...",
"comment.input.sending.progress": "Odesílání zprávy ...",
Expand Down Expand Up @@ -55,6 +59,7 @@
"header.nav.projects": "Prozkoumat projekty",
"header.nav.learn": "Naučte se",
"header.nav.aboutLink": "O stránce",
"header.nav.support": "Podpora",
"header.nav.my_contributions": "Moje zapojení",
"header.nav.manage": "Spravovat",
"header.buttons.logIn": "Přihlásit se",
Expand Down Expand Up @@ -406,6 +411,8 @@
"projects.formInputs.random_task_selection": "Vynutit náhodný výběr úlohy",
"projects.formInputs.random_task_selection.mapping": "Vynutit náhodný výběr úlohy při mapování",
"projects.formInputs.random_task_selection.description": "Pokud je zaškrtnuto, uživatelé musí editovat úkoly náhodně v počáteční fázi editace (pro správce a administrátory to neplatí).",
"projects.formInputs.rapid_power_user": "Povolení funkcí RapiD Power User",
"projects.formInputs.rapid_power_user.description": "Pokud je zaškrtnuto, načte se RapiD s povoleným dialogovým oknem power user.",
"projects.formInputs.imagery": "Mapový podklad",
"projects.formInputs.imagery.note": "Používejte tento formát adres TMS URL: {exampleUrl}",
"projects.formInputs.priority_areas.options.polygon": "Nakreslit polygon",
Expand Down Expand Up @@ -531,12 +538,25 @@
"project.stats.totalEdits": "Celkový počet úprav mapy",
"project.stats.changesets": "Sady změn",
"project.stats.edits": "Úpravy",
"project.stats.edits.info": "Tyto statistiky jsou získávány pomocí výchozího komentáře souboru změn projektu.",
"project.tasks.unsaved_map_changes.title": "Máte nějaké neuložené změny na mapě",
"project.tasks.unsaved_map_changes.split": "Chcete-li úlohu rozdělit, uložte ji nebo zrušte",
"project.tasks.unsaved_map_changes.unlock": "Chcete-li vybrat jinou úlohu, uložte ji nebo zrušte",
"project.tasks.unsaved_map_changes.actions.close_modal": "Zavřít",
"project.tasks.no_mapped_tasks_selected": "Nebyly vybrány žádné mapované úlohy",
"project.tasks.no_mapped_tasks_selected.description": "Vybrané úlohy nebylo možné uzamknout, protože žádný z nich není v namapovaném stavu.",
"project.tasks.invalid_task_state_errortitle": "Neplatný stav úlohy",
"project.tasks.invalid_task_state_error.description": "Úloha v neplatném stavu pro mapování",
"project.tasks.user_not_allowed_error.title": "Chyba Uživatel není povolen",
"project.tasks.user_not_allowed_error.description": "Mapování není povoleno, protože uživatel není na seznamu povolených uživatelů",
"project.tasks.project_not_published_error.title": "Projekt nezveřejněn",
"project.tasks.project_not_published_error.description": "Mapování není povoleno, protože projekt není zveřejněn",
"project.tasks.task_not_owned_error.title": "Úloha není vlastněna",
"project.tasks.task_not_owned_error.description": "Pokus o odemknutí úlohy vlastněné jiným uživatelem",
"project.tasks.not_ready_for_validation_error.title": "Není připraveno k validaci",
"project.tasks.not_ready_for_validation_error.description": "Úloha není MAPOVANÁ, BADIMAGERY nebo je INVALIDATED",
"project.tasks.cannot_validate_mapped_task_error.title": "Nelze validovat mapovanou úlohu",
"project.tasks.cannot_validate_mapped_task_error.description": "Úlohy nemohou být validovány stejným uživatelem, který označil úlohu jako zmapovanou nebo badimagery",
"project.tasks.josm_error": "Spojení s JOSM selhalo",
"project.tasks.josm_error.description": "Ověřte, zda je na vašem počítači spuštěn JOSM a je povoleno dálkové ovládání.",
"project.tasks.lock_error.generic": "Nepovedlo se danou úlohu pro vás uzamknout...",
Expand Down Expand Up @@ -988,6 +1008,8 @@
"pages.learn.tutorials.tm_manual.description": "Naučte se, jak najít projekt a úlohu, který vás zajímá, jak uzamknout úlohu k úpravám a vybrat vhodný editační software.",
"pages.learn.tutorials.osm_step_by_step.title": "Naučte se OpenStreetMap krok za krokem",
"pages.learn.tutorials.osm_step_by_step.description": "Průvodce pro začátečníky k mapování na OpenStreetMap",
"pages.learn.tutorials.cheatsheet.title": "Tasking Manager Cheatsheet",
"pages.learn.tutorials.cheatsheet.description": "Stručný soubor poznámek TM sloužící k rychlému nahlédnutí.",
"pages.learn.tutorials.learnosm.title": "Průvodce administrací",
"pages.learn.tutorials.learnosm.description": "Manuál o tom, jak vytvářet a spravovat projekty v Tasking Manageru",
"pages.learn.map.steps.project.title": "Vyberte projekt",
Expand Down Expand Up @@ -1021,9 +1043,11 @@
"pages.learn.validate.note": "Jakmile se v komunitě OpenStreetMap stanete zkušeným mapovačem, získáte jistotu, že jste připraveni se stát validátorem. Můžete se přihlásit do některého z ověřovacích týmů nebo najít projekt, na kterém chcete ověřit. Připojte se k týmu, který vám dá oprávnění k ověření úloh. Nyní máte příležitost udělat krok vpřed a pomoci ostatním mapovačům na jejich cestě",
"pages.learn.manage_title": "Naučte se řídit",
"pages.learn.manage.intro": "Schopnost organizovat mapovací úsilí je obrovskou příležitostí pro rychlý a koordinovaný sběr dat. Abyste byli úspěšní, musíte být schopni motivovat komunitu mapovačů.",
"pages.learn.manage.description": "Pomocí Tasking Manageru můžete nastavit vlastní projekty. Nezapomeňte být zodpovědní tím, že zajistíte, aby vaše úroveň dovedností odpovídala vašim ambicím. Je dobré obrátit se na správce Tasking Manageru a dozvědět se více o tom, co je potřeba k získání oprávnění k vytváření a správě projektů.",
"pages.learn.manage.description": "Pomocí Tasking Manageru můžete nastavit vlastní projekty. Ujistěte se, že jste zodpovědní a že úroveň vašich dovedností odpovídá vašim ambicím. Pokud máte zájem o vytváření projektů, zkontrolujte, zda vaše organizace již existuje v Tasking Manageru, zobrazením tohoto {organizationsListLink}. Pokud vaše organizace v Tasking Manageru již existuje, obraťte se na některého z manažerů organizací uvedených v seznamu. Pokud vaše organizace neexistuje, neváhejte zaregistrovat svůj zájem o vytváření projektů vyplněním tohoto {createNewOrganizationFormLink}.",
"pages.learn.manage.steps.join.title": "Staňte se součástí komunity nebo organizace",
"pages.learn.manage.steps.join.description": "Tasking Manager vám umožňuje vytvářet projekty jako součást komunity nebo organizace. Buď se spojte s tím, koho znáte, nebo požádejte administrátory o přidání vaší skupiny do Tasking Manageru.",
"pages.learn.manage.list": "seznam",
"pages.learn.manage.form": "formulář",
"pages.learn.manage.steps.create.title": "Vytvořte projekt a dejte o něm vědět",
"pages.learn.manage.steps.create.description": "Přitáhněte lidi sem, aby zmapovali váš projekt. Doporučujeme sledovat mapování vašich projektů. Nezapomeňte je správně namapovat a vyplnit.",
"pages.learn.manage.steps.data.title": "Použijte data",
Expand Down
Loading
Loading