# Internationalisation (i18n)

Les plugins NocoBase prennent en charge l'internationalisation (i18n) multilingue, aussi bien pour le frontend que pour le backend. Grâce à un mécanisme unifié, vous pouvez facilement implémenter du contenu multilingue dans vos plugins.

## Gestion des fichiers multilingues

Les fichiers multilingues de vos plugins sont centralisés dans le répertoire `src/locale`. Nous vous recommandons de les nommer en fonction de la langue, par exemple :

```bash
|- /plugin-hello
  |- /src
    |- /locale
      |- en-US.json   # Langue anglaise
      |- zh-CN.json   # Langue chinoise
```

Chaque fichier de langue exporte un objet JSON qui regroupe toutes les chaînes de traduction pour cette langue, par exemple :

```json
// zh-CN.json
{
  "Hello": "你好",
  "World": "世界",
  "Enter your name": "请输入你的名字",
  "Your name is {{name}}": "你的名字是 {{name}}"
}
```

```json
// en-US.json
{
  "Hello": "Hello",
  "World": "World",
  "Enter your name": "Enter your name",
  "Your name is {{name}}": "Your name is {{name}}"
}
```

> Lors de l'ajout initial de fichiers de langue, vous devez redémarrer l'application pour qu'ils prennent effet. Vous pouvez vérifier si les entrées de traduction sont actives via l'API :  
> http://localhost:13000/api/app:getLang?locale=zh-CN

## Instance i18n globale

`app.i18n` est l'instance i18n globale, utilisable dans les scénarios globaux des plugins ou pour la CLI. Vous pouvez la combiner avec Inquirer pour implémenter des interactions en ligne de commande :

```ts
import select from '@inquirer/select';
import input from '@inquirer/input';

export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.command('test-i18n').action(async () => {
      const answer1 = await select({
        message: 'Select a language',
        choices: [
          { name: '中文', value: 'zh-CN' },
          { name: 'English', value: 'en-US' }
        ]
      });

      await this.app.changeLanguage(answer1);

      const answer2 = await input({
        message: app.i18n.t('Enter your name')
      });

      console.log(app.i18n.t('Your name is {{name}}', { name: answer2 }));
    });
  }
}
```

> `app.i18n.t(text, options)` est utilisée pour traduire du texte et prend en charge les variables de modèle.

## i18n du contexte de requête

Pour chaque requête, `ctx.i18n` est une instance clonée de l'i18n globale. Elle répond indépendamment avec les informations multilingues en fonction de la langue du client.

Définir la langue du client

- **Chaîne de requête** :

```bash
GET /?locale=en-US HTTP/1.1
Host: localhost:13000
```

- **En-tête de requête (recommandé)** :

```bash
GET / HTTP/1.1
Host: localhost:13000
X-Locale: en-US
```

Utilisation dans un middleware

```ts
export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.use(async (ctx, next) => {
      if (ctx.path === '/api/test-i18n') {
        ctx.body = ctx.t('Hello', { ns: '@my-project/plugin-hello' });
      }
      await next();
    });
  }
}
```

Accéder à http://localhost:13000/api/test-i18n?locale=zh-CN retournera `你好` (le mot chinois pour « Hello »).

## i18n interne aux plugins

Les plugins peuvent utiliser directement `plugin.t(key, options)` pour obtenir les traductions :

```ts
export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.use(async (ctx, next) => {
      if (ctx.path === '/api/plugin-i18n') {
        ctx.body = this.plugin.t('Hello');
      }
      await next();
    });
  }
}
```

> `plugin.t(text)` est équivalent à `ctx.t(text, { ns })`.

## API associées

- app.i18n
- app.t(text, options)
- ctx.i18n
- ctx.t(text, options)
- plugin.t()
- tExpr(text, options)