Pour contribuer à la traduction ou ajouter des langues, c'est relativement simple.
Nous utilisons la bibliothèque Lingui, et nous avons globalement 5 ou 6 types de supports de traduction.
Les textes de l'interface
Paragraphes, boutons, liens : tous ces éléments sont dans le HTML ou plus précisément dans notre cas, dans le JSX, le HTML de React, la bibliothèque qui fait tourner la moitié du net.
Ils sont traduits via les fichiers .po dans locales/[lang]/messages.po. C'est un format standard, gettext.
Codeberg Translate
Pour contribuer à la traduction d'une des langues déjà prises en charge, rendez-vous sur la plateforme Codeberg Translate. Lorsque de nouveaux éléments sont ajoutés ou modifiés dans le code, la plateforme les ajoute à la liste à traduire. Dans l'autre sens, les contributions de traduction sont régulièrement intégrées au code via des pull requests (exemple : #2170).
Weblate propose des "Suggestions automatisées" (Automated Suggestions) qui viennent de Mistral. N'hésitez pas à l'utiliser pour accélerer la traduction !
LLM
Si vous traduisez directement un fichier messages.po à l'aide d'une LLM, pas de souci mais vous devez la citer dans le message de commit.
Pour aider à traduire, j'utilise aider. Il a l'avantage de bien bosser et de faire le commit automatiquement en y inscrivant la version du modèle, chose qui est requise par notre guide de contribution.
MISTRAL_API_KEY=MA_CLEF_MISTRAL aider --model mistral/mistral-large-2512 --no-gitignore locales/*/messages.po
"Fill the missing translations in the messages.po files. Only the missing translations, don't touch the others."
Les messages automatiquement traduits doivent être commentés par la ligne # auto-translated by MODÈLE en début de bloc. C'est important, pour que les traducteurs humains puissent le savoir et l'améliorer.
Ensuite, un modèle ne doit pas sauf exception changer une traduction humaine.
Internationalisation d'une chaîne de caractères
En tant que traducteur, ne vous étonnez pas ne pas trouver certaines clefs de traduction dans les fichiers .po : il faut à la main (ou via une LLM) ajouter des trucs dans le code pour chaque élément à traduire. C'est en cours, ça va être fait progressivement.
Car il faut englober tous les textes à traduire dans les balises HTML par <Trans> et {t}.
<button onClick={()=> alert('plop')}>Y aller</button>
devient
import { Trans } from '@lingui/react/macros'
<button ...><Trans>Let's go</Trans></button>
Example avec t
import { t } from '@lingui/react/macros'
<img alt={t`Un chat domestique qui empêche un oiseau d'aller picorer des vers de terre`}/>
La langue de base est le français et le restera jusqu'à nouvel ordre.
Tous ces textes sont extraits grâce à la commande bun lingui:extract dans les fichiers .po. Cette commande les marque comme "à traduire". Si vous n'êtes pas développeur ni curieux, vous pouvez ignorer cette étape et vous concentrer uniquement sur les textes déjà marqués comme à traduire.
Note : parfois il faut aussi utiliser bun run lingui:extract --clean pour nettoyer les traductions périmées ou mettre à jour les lignes des traductions.
Le fond de carte
Il est traduit automatiquement lors de la création des cartes. C'est ici qu'on ajoute des nouvelles langues. Ensuite côté client c'est pas trivial de bien traduire, cf ce ticket.
Le blog
Fichiers contenus dans /article
Tous les articles peuvent être traduits. Certains le sont en anglais. C'est simple : créer une nouvelle entrée dans /articles/ en respectant le format des autres, et en ajoutant deux attributs à l'en-tête YAML : lang: (par exemple it) et original: qui donne le slug de l'article en français qui est la source de cette traduction.
Variante : les pages qui utilisent notre moteur de blog mais qui apparaissent sur des chemins dédiés, comme cartes.app/a-propos. Il faut simplement ajouter un a-propos.[lang].mdx.
D'autres fichiers mdx ailleurs
Les attributs et tags OSM
Source des traductions
Les traductions des tags OSM viennent ... d'OSM ! C'est le iD tagging schema, c'est à dire les traductions utilisées en premier lieu dans l'éditeur iD, mais aussi dans plein d'autres outils basés sur OSM. Les modifications se font (pour tous les outils !) sur la plateforme de traductions transifex.
Le fichier json qui agrège toutes les traductions enregistrées sur transifex est disponible sur le repo github.
Intégration du fichier dans cartes.app
Son integration dans cartes.app se fait via le fichier des dépendances package.json :
"@openstreetmap/id-tagging-schema": "^6.13.4",
La MAJ du paquet se fait via la commande bun add @openstreetmap/id-tagging-schema@6.13.4. Pas facile d'automatiser, faut le faire à la main, dixit Mael.
API interne pour interrogation du fichier
voir : /app/api/tag-translations/route.ts
(à compléter avec des explications)
Gestion des exceptions
Il est possible de gérer des exceptions au moment où on interroge les presets iD dans api tag-translations.
Dans l'idéal, il faudrait l'utiliser uniquement si on veut (pour une bonne raison) forcer une traduction différente de celle d'iD. Car les nouvelles ou meilleures traductions devrait être faites directement dans transifex pour qu'elles profitent à tous (même si ça implique un peu de patience le temps que ça redescende).
Pour le support d'une nouvelle traduction, il faut donc rajouter un import dans le fichier tag-translations/route.ts. Si votre langue n'a pas encore été ajouté, vous devrez le faire à la main (ou nous demander de le faire).
Plus d'infos
Voir aussi
- #922 sur le sujet des presets iD
- #1161 sur le cas spécifique de la traduction de
access
Les catégories et autres fichiers YAML
Les catégories sont un élément très important de cartes.app. Elles permettent les filtres rapides en icônes, mais aussi le répertoire complet de la centaine de catégories ! Et puis aussi la suggestion automatique de "bar" quand on cherche "bière", grâce à leurs dictionnaires.
En plus de ça, elles construisent l'annuaire, essentiel pour les moteurs de recherche. Et puis elles permettent aussi d'afficher un icône bière sur les fiches lieux des bars. Bref, c'est important.
Pour les traduire, il faut ajouter un fichier categories.yaml dans locales/[lang]/. Regardez le fichier anglais pour comprendre ce qu'il doit comporter, ou lisez le commentaire d'en-tête ici, et celui-ci spécifique à la traduction. Ce script createLanguageCategoriesTemplate.ts est actionné via bun run translate-categories et permet de créer le fichier de traduction sur la base de la source française, qu'il n'y aura plus qu'à traduire. Le script est idempotent : il peut être utilisé également pour mettre à jour les traductions après une évolution des catégories source françaises.
Le fichier translation.md cité plus haut est aussi une instruction qui devrait permettre à une LLM de gérer cette traduction.
Par exemple via aider et Mistral.
MISTRAL_API_KEY=MA_CLEF aider --model mistral/mistral-large-2512 --no-gitignore locales/*/categories.yaml components/categories/categories.yaml components/categories/translation.md
# Puis l'instruction suivante :
# Please fill locales/br/categories.yaml with translations. Read the comment in components/categories/translation.md to understand what's to be done and follow the instructions in the comment
>
D'autres éléments divers
Pour l'instant, c'est traduit en français, et pour toutes les autres langues ça passe à l'anglais ou autre selon locales/preferences.yaml
À ajouter ici.
Pour contribuer à la traduction ou ajouter des langues, c'est relativement simple.
Nous utilisons la bibliothèque Lingui, et nous avons globalement 5 ou 6 types de supports de traduction.
## Les textes de l'interface
Paragraphes, boutons, liens : tous ces éléments sont dans le HTML ou plus précisément dans notre cas, dans le JSX, le HTML de React, la bibliothèque qui fait tourner la moitié du net.
Ils sont traduits via les `fichiers .po` dans [`locales/[lang]/messages.po`](https://codeberg.org/cartes/web/src/branch/master/locales). C'est un format standard, gettext.
### Codeberg Translate
Pour contribuer à la traduction d'une des langues déjà prises en charge, rendez-vous sur la plateforme [Codeberg Translate](https://translate.codeberg.org/projects/cartes/web/messages). Lorsque de nouveaux éléments sont ajoutés ou modifiés dans le code, la plateforme les ajoute à la liste à traduire. Dans l'autre sens, les contributions de traduction sont régulièrement intégrées au code via des pull requests (exemple : https://codeberg.org/cartes/web/pulls/2170).
Weblate propose des "Suggestions automatisées" (Automated Suggestions) qui viennent de Mistral. N'hésitez pas à l'utiliser pour accélerer la traduction !
### LLM
Si vous traduisez directement un fichier messages.po à l'aide d'une LLM, pas de souci mais vous devez la citer dans le message de commit.
Pour aider à traduire, j'utilise `aider`. Il a l'avantage de bien bosser et de faire le commit automatiquement en y inscrivant la version du modèle, chose qui est requise par notre [guide de contribution](https://codeberg.org/cartes/web/src/branch/master/CONTRIBUTING.md).
```
MISTRAL_API_KEY=MA_CLEF_MISTRAL aider --model mistral/mistral-large-2512 --no-gitignore locales/*/messages.po
"Fill the missing translations in the messages.po files. Only the missing translations, don't touch the others."
```
Les messages automatiquement traduits doivent être commentés par la ligne `# auto-translated by MODÈLE` en début de bloc. C'est important, pour que les traducteurs humains puissent le savoir et l'améliorer.
Ensuite, un modèle *ne doit pas sauf exception* changer une traduction humaine.
### Internationalisation d'une chaîne de caractères
En tant que traducteur, **ne vous étonnez pas ne pas trouver certaines clefs de traduction dans les fichiers .po** : il faut à la main (ou via une LLM) ajouter des trucs dans le code pour chaque élément à traduire. C'est en cours, ça va être fait progressivement.
> Car il faut englober tous les textes à traduire dans les balises HTML par `<Trans>` et `{t}`.
> ```
> <button onClick={()=> alert('plop')}>Y aller</button>
> ```
> devient
> ```
> import { Trans } from '@lingui/react/macros'
> <button ...><Trans>Let's go</Trans></button>
> ```
> Example avec `t`
> ```
> import { t } from '@lingui/react/macros'
> <img alt={t`Un chat domestique qui empêche un oiseau d'aller picorer des vers de terre`}/>
> ```
**La langue de base est le français et le restera jusqu'à nouvel ordre**.
Tous ces textes sont extraits grâce à la commande `bun lingui:extract` dans les fichiers .po. Cette commande les marque comme "à traduire". Si vous n'êtes pas développeur ni curieux, vous pouvez ignorer cette étape et vous concentrer uniquement sur les textes déjà marqués comme à traduire.
> Note : parfois il faut aussi utiliser `bun run lingui:extract --clean` pour nettoyer les traductions périmées ou mettre à jour les lignes des traductions.
## Le fond de carte
Il est traduit automatiquement lors de la création des cartes. C'est [ici qu'on ajoute des nouvelles langues](https://codeberg.org/cartes/serveur/src/branch/master/tilemaker/resources/process-openmaptiles.lua#L16-L18). Ensuite côté client c'est pas trivial de bien traduire, cf [ce ticket](https://codeberg.org/cartes/web/issues/1788).
## Le blog
Fichiers contenus dans [/article](https://codeberg.org/cartes/web/src/branch/master/articles)
Tous les articles peuvent être traduits. Certains le sont en anglais. C'est simple : créer une nouvelle entrée dans `/articles/` en respectant le format des autres, et en ajoutant deux attributs à l'en-tête YAML : `lang: ` (par exemple `it`) et `original: ` qui donne le `slug` de l'article en français qui est la source de cette traduction.
Variante : les pages qui utilisent notre moteur de blog mais qui apparaissent sur des chemins dédiés, comme cartes.app/a-propos. Il faut simplement ajouter un `a-propos.[lang].mdx`.
## D'autres fichiers mdx ailleurs
- [components/explanations.mdx](https://codeberg.org/cartes/web/src/branch/master/components/explanations.mdx)
- [components/news/news.yaml](https://codeberg.org/cartes/web/src/branch/master/components/news/news.yaml)
## Les attributs et tags OSM
### Source des traductions
Les traductions des tags OSM viennent ... d'OSM ! C'est le [`iD tagging schema`](https://github.com/openstreetmap/id-tagging-schema), c'est à dire les traductions utilisées en premier lieu dans l'éditeur iD, mais aussi dans plein d'autres outils basés sur OSM. Les modifications se font (pour tous les outils !) sur la plateforme de traductions [transifex](https://app.transifex.com/openstreetmap/id-editor/dashboard/).
Le fichier json qui agrège toutes les traductions enregistrées sur transifex est [disponible sur le repo github](https://github.com/openstreetmap/id-tagging-schema/blob/main/dist/translations/fr.json).
### Intégration du fichier dans cartes.app
Son integration dans cartes.app se fait via le fichier des dépendances `package.json` :
https://codeberg.org/cartes/web/src/commit/fa885e80af96c9e250b27cadba0632b381e49707/package.json#L51
La MAJ du paquet se fait via la commande `bun add @openstreetmap/id-tagging-schema@6.13.4`. Pas facile d'automatiser, faut le faire à la main, dixit Mael.
### API interne pour interrogation du fichier
voir : [/app/api/tag-translations/route.ts](https://codeberg.org/cartes/web/src/branch/master/app/api/tag-translations/route.ts)
(à compléter avec des explications)
### Gestion des exceptions
Il est possible de gérer des exceptions au moment où on interroge les presets iD dans [ api tag-translations](https://codeberg.org/cartes/web/src/branch/master/app/api/tag-translations/route.ts).
Dans l'idéal, il faudrait l'utiliser uniquement si on veut (pour une bonne raison) forcer une traduction différente de celle d'iD. Car les nouvelles ou meilleures traductions devrait être faites directement dans [transifex](https://app.transifex.com/openstreetmap/id-editor/dashboard/) pour qu'elles profitent à tous (même si ça implique un peu de patience le temps que ça redescende).
Pour le support d'une nouvelle traduction, il faut donc rajouter un import dans [le fichier `tag-translations/route.ts`](https://codeberg.org/cartes/web/src/commit/master/app/api/tag-translations/route.ts). Si votre langue n'a pas encore été ajouté, vous devrez le faire à la main (ou nous demander de le faire).
### Plus d'infos
Voir aussi
- #922 sur le sujet des presets iD
- #1161 sur le cas spécifique de la traduction de `access`
## Les catégories et autres fichiers YAML
Les catégories sont un élément très important de cartes.app. Elles permettent les filtres rapides en icônes, mais aussi le répertoire complet de la centaine de catégories ! Et puis aussi la suggestion automatique de "bar" quand on cherche "bière", grâce à leurs dictionnaires.
En plus de ça, elles construisent l'[annuaire](https://cartes.app/lieux), essentiel pour les moteurs de recherche. Et puis elles permettent aussi d'afficher un icône bière sur les fiches lieux des bars. Bref, c'est important.
Pour les traduire, il faut ajouter un fichier `categories.yaml` dans `locales/[lang]/`. Regardez le fichier anglais pour comprendre ce qu'il doit comporter, ou lisez le commentaire d'en-tête [ici](https://codeberg.org/cartes/web/src/branch/master/components/categories/createLanguageCategoriesTemplate.ts#L8), et [celui-ci spécifique à la traduction](https://codeberg.org/cartes/web/src/branch/master/components/categories/translation.md). Ce script `createLanguageCategoriesTemplate.ts` est actionné via `bun run translate-categories` et permet de créer le fichier de traduction sur la base de la source française, qu'il n'y aura plus qu'à traduire. Le script est idempotent : il peut être utilisé également pour mettre à jour les traductions après une évolution des catégories source françaises.
Le fichier `translation.md` cité plus haut est aussi une instruction qui devrait permettre à une LLM de gérer cette traduction.
Par exemple via `aider` et Mistral.
```
MISTRAL_API_KEY=MA_CLEF aider --model mistral/mistral-large-2512 --no-gitignore locales/*/categories.yaml components/categories/categories.yaml components/categories/translation.md
# Puis l'instruction suivante :
# Please fill locales/br/categories.yaml with translations. Read the comment in components/categories/translation.md to understand what's to be done and follow the instructions in the comment
>
```
## D'autres éléments divers
- Ajouter les jours de la semaine dans le fichier [app/osm/edit/ohEncoder.ts](https://codeberg.org/cartes/web/src/branch/master/app/osm/edit/ohEncoder.ts)
- Traduire [les éléments cartographiques de l'interface qui sont gérés par MapLibre](https://codeberg.org/cartes/web/src/commit/ec24d424b8e2c2cf79d96a1cc5979b1d6fdc2b60/components/map/frenchMaplibreLocale.ts)
Pour l'instant, c'est traduit en français, et pour toutes les autres langues ça passe à l'anglais ou autre selon locales/preferences.yaml
À ajouter ici.