> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Localisation

> Gestion des chaînes de traduction avec les fichiers PHP et JSON de Laravel.

## Qu'est-ce que la localisation

La localisation de Laravel offre un mécanisme pratique pour récupérer des chaînes traduites dans plusieurs langues.
Utile pour prendre en charge plusieurs langues dans votre application.

Deux formats sont disponibles :

| Format   | Caractéristiques                                                                                                           |
| -------- | -------------------------------------------------------------------------------------------------------------------------- |
| **PHP**  | Tableaux clé/valeur comme `lang/ja/messages.php`. Adapté à l'organisation par fonctionnalité (erreurs de validation, etc.) |
| **JSON** | Chaînes directement en clé dans `lang/ja.json`. Recommandé pour les applications avec beaucoup de traductions              |

<Info>
  Le répertoire `lang` n'existe pas par défaut. Publiez-le via `lang:publish`.
</Info>

```shell theme={null}
php artisan lang:publish
```

## Configuration de la locale

### Locale par défaut

Définie via `locale` dans `config/app.php`, typiquement pilotée par `APP_LOCALE`.

```php theme={null}
// config/app.php
'locale' => env('APP_LOCALE', 'en'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
```

```ini theme={null}
# .env
APP_LOCALE=fr
APP_FALLBACK_LOCALE=en
```

`fallback_locale` : locale utilisée en secours si la traduction n'existe pas.

### Changer la locale à l'exécution

`App::setLocale()` change la locale pour la requête.

```php theme={null}
use Illuminate\Support\Facades\App;

Route::get('/greeting/{locale}', function (string $locale) {
    if (! in_array($locale, ['en', 'fr', 'ja'])) {
        abort(400);
    }

    App::setLocale($locale);

    // ...
});
```

### Consulter la locale actuelle

```php theme={null}
use Illuminate\Support\Facades\App;

$locale = App::currentLocale();

if (App::isLocale('fr')) {
    // Traitement français
}
```

## Créer les fichiers de langue

### Format PHP

Créez un fichier PHP dans `lang/{code}/`. Retournez un tableau clé/valeur.

```text theme={null}
/lang
    /en
        messages.php
    /fr
        messages.php
```

```php theme={null}
<?php

// lang/fr/messages.php

return [
    'welcome' => 'Bienvenue dans l\'application !',
    'goodbye' => 'À bientôt !',
];
```

<Warning>
  Pour les variantes régionales, respectez ISO 15897. Par exemple, anglais britannique = `en_GB`, pas `en-gb`.
</Warning>

### Format JSON

Recommandé quand il y a beaucoup de chaînes.
Créez `lang/{code}.json`.

```text theme={null}
/lang
    en.json
    fr.json
```

Les clés sont les chaînes en langue par défaut (anglais).

```json theme={null}
{
    "Welcome to our application!": "Bienvenue dans notre application !",
    "I love programming.": "J'adore programmer.",
    "Logout": "Déconnexion",
    "Dashboard": "Tableau de bord"
}
```

<Tip>
  En JSON, la chaîne anglaise sert de clé, ce qui garantit un affichage anglais par défaut. Si un fichier de langue manque, la clé (texte anglais) apparaît telle quelle.
</Tip>

### Choix entre PHP et JSON

<AccordionGroup>
  <Accordion title="Cas idéaux pour le format PHP">
    * Organisation par fonctionnalité (messages de validation, etc.)
    * Personnalisation des traductions intégrées de Laravel (`validation.php`, `auth.php`)
    * Besoin d'une hiérarchie de clés

    ```php theme={null}
    // lang/fr/validation.php
    return [
        'required' => 'Le champ :attribute est obligatoire.',
        'email' => 'Le champ :attribute doit être une adresse e-mail valide.',
    ];
    ```
  </Accordion>

  <Accordion title="Cas idéaux pour le format JSON">
    * Beaucoup de textes d'UI, sans envie d'inventer des clés
    * On écrit l'anglais dans les templates et on gère les autres langues via traduction
    * Internationalisation ajoutée après coup

    ```blade theme={null}
    {{-- Anglais directement dans le template --}}
    {{ __('Welcome to our application!') }}
    ```
  </Accordion>
</AccordionGroup>

## Lire les traductions

### Helper `__()`

Le plus courant. En PHP, notation `fichier.clé`.

```php theme={null}
// Format PHP : clé 'welcome' de lang/fr/messages.php
echo __('messages.welcome');
// => Bienvenue dans l'application !

// Format JSON : passez la chaîne source
echo __('I love programming.');
// => J'adore programmer.
```

Si la traduction est absente, la clé est renvoyée telle quelle.

```php theme={null}
echo __('messages.not_exists');
// => messages.not_exists
```

### Dans Blade

Utilisez `{{ __() }}`.

```blade theme={null}
{{-- Format PHP --}}
<h1>{{ __('messages.welcome') }}</h1>

{{-- Format JSON --}}
<button>{{ __('Logout') }}</button>

{{-- Directive @lang (obsolète, conservée pour compatibilité) --}}
@lang('messages.welcome')
```

<Tip>
  La directive `@lang` est dépréciée. Utilisez `{{ __() }}`.
</Tip>

## Placeholders

Vous pouvez inclure des placeholders `:nom`.

```php theme={null}
// lang/fr/messages.php
return [
    'welcome' => 'Bienvenue, :name !',
    'greet'   => 'Bonjour, :Name !',  // Première lettre en majuscule
    'shout'   => 'SALUT :NAME !',     // Tout en majuscules
];
```

Passez le tableau de remplacements en 2ᵉ argument.

```php theme={null}
echo __('messages.welcome', ['name' => 'Tanaka']);
// => Bienvenue, Tanaka !

echo __('messages.greet', ['name' => 'taro']);
// => Bonjour, Taro !

echo __('messages.shout', ['name' => 'taro']);
// => SALUT TARO !
```

Idem dans Blade.

```blade theme={null}
<p>{{ __('messages.welcome', ['name' => $user->name]) }}</p>
```

## Pluralisation

Les règles de pluriel varient selon la langue. Laravel utilise `|` pour distinguer singulier et pluriel.

### Pluriel simple

```php theme={null}
// lang/fr/messages.php
return [
    'apples' => 'Il y a une pomme|Il y a plusieurs pommes',
];
```

Idem en JSON :

```json theme={null}
{
    "There is one apple|There are many apples": "Il y a une pomme|Il y a plusieurs pommes"
}
```

Passez la quantité à `trans_choice()`.

```php theme={null}
echo trans_choice('messages.apples', 1);
// => Il y a une pomme

echo trans_choice('messages.apples', 5);
// => Il y a plusieurs pommes
```

### Plages

Vous pouvez préciser des plages.

```php theme={null}
'apples' => '{0} Aucune pomme|[1,19] Quelques pommes|[20,*] Beaucoup de pommes',
```

```php theme={null}
echo trans_choice('messages.apples', 0);
// => Aucune pomme

echo trans_choice('messages.apples', 10);
// => Quelques pommes

echo trans_choice('messages.apples', 50);
// => Beaucoup de pommes
```

### Placeholders dans le pluriel

`:count` affiche la quantité. Passez d'autres valeurs en 3ᵉ argument.

```php theme={null}
// lang/fr/messages.php
return [
    'minutes_ago' => '{1} il y a :value minute|[2,*] il y a :value minutes',
    'items'       => ':count éléments présents',
];
```

```php theme={null}
echo trans_choice('messages.minutes_ago', 5, ['value' => 5]);
// => il y a 5 minutes

echo trans_choice('messages.items', 3);
// => 3 éléments présents
```

## Surcharger un fichier de langue d'un package

Pour surcharger un fichier fourni par un package tiers, placez un fichier de même nom dans `lang/vendor/{package}/{locale}/`.

Pour personnaliser les messages anglais du package `skyrim/hearthfire` :

```text theme={null}
lang/
└── vendor/
    └── hearthfire/
        └── en/
            └── messages.php
```

```php theme={null}
// lang/vendor/hearthfire/en/messages.php
return [
    'welcome' => 'Message personnalisé',
    // Ne définissez que les clés à surcharger. Les autres viennent du fichier d'origine.
];
```

## Exemple : middleware français / anglais

Middleware qui bascule la locale selon la session, la préférence utilisateur ou l'URL.

<Steps>
  <Step title="Créer le middleware">
    ```shell theme={null}
    php artisan make:middleware SetLocale
    ```
  </Step>

  <Step title="Implémenter">
    ```php theme={null}
    <?php

    namespace App\Http\Middleware;

    use Closure;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\App;
    use Symfony\Component\HttpFoundation\Response;

    class SetLocale
    {
        public function handle(Request $request, Closure $next): Response
        {
            // Locales supportées
            $supportedLocales = ['fr', 'en'];

            // Utiliser la locale en session si présente
            $locale = $request->session()->get('locale');

            // Sinon, se fier à Accept-Language du navigateur
            if (! $locale) {
                $browserLocale = substr($request->getPreferredLanguage($supportedLocales) ?? 'fr', 0, 2);
                $locale = in_array($browserLocale, $supportedLocales) ? $browserLocale : 'fr';
            }

            App::setLocale($locale);

            return $next($request);
        }
    }
    ```
  </Step>

  <Step title="Enregistrer le middleware">
    Dans `bootstrap/app.php`.

    ```php theme={null}
    use App\Http\Middleware\SetLocale;

    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(SetLocale::class);
    })
    ```
  </Step>

  <Step title="Route de changement de locale">
    ```php theme={null}
    // routes/web.php
    Route::post('/locale/{locale}', function (string $locale) {
        if (! in_array($locale, ['fr', 'en'])) {
            abort(400);
        }

        session(['locale' => $locale]);

        return back();
    })->name('locale.switch');
    ```
  </Step>

  <Step title="Boutons de switch dans Blade">
    ```blade theme={null}
    <div>
        <form method="POST" action="{{ route('locale.switch', 'fr') }}">
            @csrf
            <button type="submit">Français</button>
        </form>

        <form method="POST" action="{{ route('locale.switch', 'en') }}">
            @csrf
            <button type="submit">English</button>
        </form>
    </div>
    ```
  </Step>
</Steps>

### Exemple d'organisation des fichiers

```text theme={null}
lang/
├── fr.json          # JSON (UI)
├── en.json
├── fr/
│   └── validation.php   # PHP (validation)
└── en/
    └── validation.php
```

```json theme={null}
// lang/fr.json
{
    "Dashboard": "Tableau de bord",
    "Login": "Connexion",
    "Logout": "Déconnexion",
    "Welcome, :name!": "Bienvenue, :name !",
    "Save": "Enregistrer",
    "Cancel": "Annuler",
    "Are you sure?": "Êtes-vous sûr ?"
}
```

```blade theme={null}
{{-- resources/views/layouts/app.blade.php --}}
<nav>
    <a href="{{ route('dashboard') }}">{{ __('Dashboard') }}</a>
    <span>{{ __('Welcome, :name!', ['name' => auth()->user()->name]) }}</span>

    <form method="POST" action="{{ route('logout') }}">
        @csrf
        <button type="submit">{{ __('Logout') }}</button>
    </form>
</nav>
```

## Récapitulatif

<AccordionGroup>
  <Accordion title="Définir des traductions">
    | Format | Chemin                 | Exemple de clé       | Lecture                  |
    | ------ | ---------------------- | -------------------- | ------------------------ |
    | PHP    | `lang/fr/messages.php` | `'welcome' => '...'` | `__('messages.welcome')` |
    | JSON   | `lang/fr.json`         | `"Welcome": "..."`   | `__('Welcome')`          |
  </Accordion>

  <Accordion title="Fonctions et façades courantes">
    | Fonction / méthode            | Rôle                             |
    | ----------------------------- | -------------------------------- |
    | `__('key')`                   | Helper pour lire une traduction  |
    | `trans('key')`                | Équivalent de `__()`             |
    | `trans_choice('key', $count)` | Traduction pluralisée            |
    | `App::setLocale('fr')`        | Change la locale pour la requête |
    | `App::currentLocale()`        | Locale courante                  |
    | `App::isLocale('fr')`         | Test de la locale                |
  </Accordion>

  <Accordion title="Utilisation dans Blade">
    ```blade theme={null}
    {{-- Base --}}
    {{ __('messages.welcome') }}

    {{-- Avec placeholder --}}
    {{ __('messages.welcome', ['name' => $user->name]) }}

    {{-- Pluriel --}}
    {{ trans_choice('messages.apples', $count) }}
    ```
  </Accordion>
</AccordionGroup>
