Skip to content

Commit

Permalink
docs: mise à jour doc i18n [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
ocruze authored and slafayIGN committed Dec 20, 2024
1 parent 79ad05d commit 4e9dba0
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 32 deletions.
4 changes: 2 additions & 2 deletions assets/i18n/languages/en.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { EspaceCoCommunitiesEnTranslations } from "../../espaceco/pages/communit
import { TMSStyleFilesManagerEnTranslations } from "../../modules/Style/TMSStyleFilesManager/TMSStyleFilesManager.locale";
import { BreadcrumbEnTranslations } from "../../modules/entrepot/breadcrumbs/Breadcrumb.locale";
import { LoginDisabledEnTranslations } from "../../pages/LoginDisabled/LoginDisabled.locale";
import { contactEnTranslations } from "../../pages/assistance/contact/Contact.locale";
import { ContactEnTranslations } from "../../pages/assistance/contact/Contact.locale";
import { mapboxStyleValidationEnTranslations } from "../../validations/mapbox/MapboxStyleValidator.locale";
import { SldStyleValidationErrorsEnTranslations } from "../../validations/sld/SldStyleValidation.locale";
import { commonEnTranslations } from "../Common.locale";
Expand All @@ -55,7 +55,7 @@ export const translations: Translations<"en"> = {
Permissions: PermissionsEnTranslations,
ValidationMetadatas: ValidationMetadatasEnTranslations,
MetadatasForm: MetadatasFormEnTranslations,
Contact: contactEnTranslations,
Contact: ContactEnTranslations,
AccessesRequest: AccessesRequestEnTranslations,
navItems: navItemsEnTranslations,
datastoreNavItems: datastoreNavItemsEnTranslations,
Expand Down
4 changes: 2 additions & 2 deletions assets/i18n/languages/fr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { EspaceCoCommunitiesFrTranslations } from "../../espaceco/pages/communit
import { TMSStyleFilesManagerFrTranslations } from "../../modules/Style/TMSStyleFilesManager/TMSStyleFilesManager.locale";
import { BreadcrumbFrTranslations } from "../../modules/entrepot/breadcrumbs/Breadcrumb.locale";
import { LoginDisabledFrTranslations } from "../../pages/LoginDisabled/LoginDisabled.locale";
import { contactFrTranslations } from "../../pages/assistance/contact/Contact.locale";
import { ContactFrTranslations } from "../../pages/assistance/contact/Contact.locale";
import { mapboxStyleValidationFrTranslations } from "../../validations/mapbox/MapboxStyleValidator.locale";
import { SldStyleValidationErrorsFrTranslations } from "../../validations/sld/SldStyleValidation.locale";
import { commonFrTranslations } from "../Common.locale";
Expand All @@ -55,7 +55,7 @@ export const translations: Translations<"fr"> = {
Permissions: PermissionsFrTranslations,
MetadatasForm: MetadatasFormFrTranslations,
ValidationMetadatas: ValidationMetadatasFrTranslations,
Contact: contactFrTranslations,
Contact: ContactFrTranslations,
AccessesRequest: AccessesRequestFrTranslations,
navItems: navItemsFrTranslations,
datastoreNavItems: datastoreNavItemsFrTranslations,
Expand Down
4 changes: 2 additions & 2 deletions assets/pages/assistance/contact/Contact.locale.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const { i18n } = declareComponentKeys<
>()("Contact");
export type I18n = typeof i18n;

export const contactFrTranslations: Translations<"fr">["Contact"] = {
export const ContactFrTranslations: Translations<"fr">["Contact"] = {
title: "Nous écrire",
mandatory_fields: "Sauf mention contraire “(optionnel)” dans le label, tous les champs sont obligatoires.",
"form.error_title": "Votre message n'a pas pu être envoyé",
Expand Down Expand Up @@ -59,7 +59,7 @@ export const contactFrTranslations: Translations<"fr">["Contact"] = {
),
};

export const contactEnTranslations: Translations<"en">["Contact"] = {
export const ContactEnTranslations: Translations<"en">["Contact"] = {
title: "Contact us",
mandatory_fields: "All fields are mandatory unless label states “optional”",
"form.error_title": "Your message could not be sent",
Expand Down
75 changes: 49 additions & 26 deletions docs/developer/i18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@ A compléter

## Côté front

L'internationalisation du site cartes.gouv.fr est réalisé avec la librairie [i18nifty](https://www.npmjs.com/package/i18nifty).
L'internationalisation du site cartes.gouv.fr est réalisée avec la librairie [i18nifty](https://www.npmjs.com/package/i18nifty).

Les chaines sont stockées dans chacun des composants React. Elles sont ainsi en de très nombreux endroits du code source mais au plus proche de leur utilisation réelle.
Les chaînes sont habituellement regroupées par un composant, ou parfois par un groupe de composants d'un même contexte. Elles sont stockées dans un fichier dédié à côté du ou des fichiers où elles sont utilisées. Elles sont ainsi en de très nombreux endroits du code source mais au plus proche de leur utilisation réelle.

Voici un exemple d'utilisation avec le composant `Contact` :
> [!IMPORTANT]
> Convention de nommage :
> **[nom du composant]locale.tsx**
- Déclarer **toutes** les clés des textes (dans le fichier du composant) :
Voici un exemple d'utilisation avec le composant `Contact` (pages/contact/Contact.tsx) :

1. Créer un fichier `Contact.locale.tsx` dans pages/contact

2. Déclarer **toutes** les clés des textes dans ce fichier :

```tsx
// Contact.tsx
import { JSX } from "react";
import { declareComponentKeys } from "../i18n/i18n";

export const { i18n } = declareComponentKeys<
const { i18n } = declareComponentKeys<
| "title"
| "mandatory_fields"
| "form.error_title"
Expand All @@ -28,33 +34,43 @@ export const { i18n } = declareComponentKeys<
| "form.email_contact_hint"
| "form.email_contact_mandatory_error"
| "documentation"
>()({
Contact,
});
| { K: "warning"; R: ReactNode }
| { K: "field_required"; P: { name: string } }
>()("Contact");
export type I18n = typeof i18n;
```

> [!NOTE]
>
> - K : la clé (obligatoire)
> - P : le type des paramètres de la fonction (optionnel, undefined par défaut)
> - R : le type de la valeur retournée par la fonction (optionnel, string par défaut)
>
> Pour un texte simple, il suffit de déclarer la clé, par exemple "mandatory_fields" ou "title".
>
> Pour une fonction, il faut déclarer :
> Pour retourner une chaîne mais avec des interpolations, il suffit de déclarer la clé et le type des paramètres, par exemple "field_required".
>
> Pour retourner autre chose que du texte mais sans forcément avoir de paramètres, il suffit de déclarer la clé et le type de retour, par exemple "warning".
>
> - K : la clé
> - P : le type des paramètres de la fonction
> - R : le type de la valeur retournée par la fonction
> Le cas maxi, pour retourner autre chose que du texte avec des interpolations, il faut déclarer les trois K, P et R, par exemple "form.explanation"
- Ajouter le retour `i18n` de `declareComponentKeys` à `ComponentKey` dans le fichier `i18n/i18n.ts` (qui est une union de toutes les déclaration de clés) :
3. Ajouter le type retourné `I18n` de `declareComponentKeys` à `ComponentKey` dans le fichier `i18n/types.ts` (qui est une union de toutes les déclaration de clés) :

```tsx
// i18n/i18n.ts
export type ComponentKey = typeof import("../pages/contact/Contact").i18n | typeof import("../config/navItems").i18n;
// i18n/types.ts
export type ComponentKey =
| import("../pages/contact/Contact").I18n
| import("../config/navItems").I18n
| ...
```
- Ajouter les textes traduits pour chaque langue (dans le fichier du composant)
4. Ajouter les textes traduits pour chaque langue (dans le fichier `.locale.tsx`)
```tsx
// Contact.tsx
import { type Translations } from "../../i18n/i18n";
// Contact.locale.tsx
import type { Translations } from "../../../i18n/types";

export const contactFrTranslations: Translations<"fr">["Contact"] = {
export const ContactFrTranslations: Translations<"fr">["Contact"] = {
title: "Nous écrire",
mandatory_fields: "Sauf mention contraire “(optionnel)” dans le label, tous les champs sont obligatoires.",
"form.error_title": "Votre message n'a pas pu être envoyé",
Expand All @@ -69,9 +85,11 @@ export const contactFrTranslations: Translations<"fr">["Contact"] = {
"form.email_contact_hint": "Format attendu : nom@domaine.fr",
"form.email_contact_mandatory_error": "Veuillez saisir une adresse email",
documentation: "Documentation",
warning: <Alert severity="error" title="Une erreur est survenue" className={fr.cx("fr-my-3w")} />,
field_required: ({ name }) => `Champ ${name} est obligatoire`,
};

export const contactEnTranslations: Translations<"en">["Contact"] = {
export const ContactEnTranslations: Translations<"en">["Contact"] = {
title: "Contact us",
mandatory_fields: "All fields are mandatory unless label states “optional”",
"form.error_title": "Your message could not be sent",
Expand All @@ -86,28 +104,33 @@ export const contactEnTranslations: Translations<"en">["Contact"] = {
"form.email_contact_hint": "Expected format: name@domain.fr",
"form.email_contact_mandatory_error": "Enter an email address",
documentation: undefined,
warning: undefined,
field_required: undefined,
};
```

> ❗ Garder une homogénéité des noms de ces variables : **[nom du composant][langue]Translations**
> [!IMPORTANT]
> Garder une homogénéité des noms de ces variables :
> **[nom du composant][langue]Translations**
> [!NOTE]
> Même si tous les textes ne sont pas traduits dans chaque langue, il faut quand-même déclarer la clé pour toutes les langues en la mettant à `undefined`, comme c'est le cas de `"documentation"`
- Importer et ajouter les textes de traduction de chaque composant dans les fichiers d'agrégation par langue :
5. Importer et ajouter les textes de traduction de chaque composant dans les fichiers d'agrégation par langue :

```tsx
// i18n/languages/fr.tsx et i18n/languages/en.tsx
import type { Translations } from "../i18n/i18n";
import type { Translations } from "../i18n/types";
import { navItemsFrTranslations } from "../../config/navItems";
import { contactFrTranslations } from "../../pages/contact/Contact";
import { ContactFrTranslations } from "../../pages/contact/Contact";

export const translations: Translations<"fr"> = {
Contact: contactFrTranslations,
Contact: ContactFrTranslations,
navItems: navItemsFrTranslations,
};
```

- Utiliser les textes de traduction :
6. Utiliser les textes de traduction :

```tsx
// Contact.tsx
Expand Down

0 comments on commit 4e9dba0

Please sign in to comment.