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

# Lokalisatie

> Leer hoe je met de meertaligheidsfunctionaliteit van Laravel vertaalstrings beheert in PHP- en JSON-bestanden.

## Wat is lokalisatie

De lokalisatiefunctionaliteit van Laravel biedt een handig mechanisme om vertaalstrings in meerdere talen op te halen.
Je gebruikt dit om meerdere talen in je applicatie te ondersteunen.

Er zijn twee manieren om vertaalstrings te beheren.

| Methode           | Kenmerken                                                                                                                      |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **PHP-bestanden** | Key-value-arrays zoals `lang/ja/messages.php`. Geschikt wanneer je per functionaliteit wilt organiseren, zoals validatiefouten |
| **JSON-formaat**  | Vertaalstrings direct als sleutel gedefinieerd in `lang/ja.json`. Aanbevolen voor applicaties met veel te vertalen tekst       |

<Info>
  Een standaard Laravel-applicatie bevat geen `lang`-directory. Om aan te passen publiceer je die met het Artisan-commando `lang:publish`.
</Info>

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

## De locale instellen

### Standaardlocale

De standaardtaal van de applicatie stel je in via `locale` in `config/app.php`.
Meestal gebruik je de omgevingsvariabele `APP_LOCALE` in het `.env`-bestand.

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

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

`fallback_locale` is de terugvaltaal wanneer een vertaalstring niet bestaat in de opgegeven taal.

### De locale tijdens runtime wijzigen

Met de methode `setLocale()` van de `App`-facade wijzig je de locale per request.

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

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

    App::setLocale($locale);

    // ...
});
```

### De huidige locale controleren

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

$locale = App::currentLocale();

if (App::isLocale('ja')) {
    // Logica voor Japans
}
```

## Taalbestanden aanmaken

### PHP-bestanden

Maak PHP-bestanden aan in de directory `lang/{taalcode}/`. Ze geven een key-value-array terug.

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

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

// lang/nl/messages.php

return [
    'welcome' => 'Welkom bij de applicatie!',
    'goodbye' => 'Tot ziens!',
];
```

<Warning>
  Voor talen met regionale varianten geef je de directory een naam volgens ISO 15897. Brits Engels is bijvoorbeeld `en_GB`, niet `en-gb`.
</Warning>

### JSON-formaat

Heb je veel te vertalen strings, dan wordt het JSON-formaat aanbevolen.
Maak in de `lang/`-directory een JSON-bestand aan met de taalcode als naam.

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

Je definieert de standaardvertaalstrings (Engels) als sleutel.

```json theme={null}
{
    "Welcome to our application!": "Welkom bij onze applicatie!",
    "I love programming.": "Ik ben dol op programmeren.",
    "Logout": "Uitloggen",
    "Dashboard": "Dashboard"
}
```

<Tip>
  In het JSON-formaat is de Engelse zin zelf de sleutel, waardoor de Engelse standaardweergave automatisch werkt. Bij talen zonder vertaalbestand wordt de sleutel (de Engelse brontekst) als zodanig getoond.
</Tip>

### PHP-bestanden versus JSON-formaat

<AccordionGroup>
  <Accordion title="Wanneer PHP-bestanden geschikt zijn">
    * Wanneer je per functionaliteit wilt organiseren, zoals validatiefoutmeldingen
    * Wanneer je de ingebouwde vertalingen van Laravel (`validation.php`, `auth.php` enz.) wilt overschrijven
    * Wanneer je hiërarchisch sleutelbeheer nodig hebt

    ```php theme={null}
    // lang/nl/validation.php
    return [
        'required' => 'Het veld :attribute is verplicht.',
        'email' => 'Het veld :attribute moet een geldig e-mailadres zijn.',
    ];
    ```
  </Accordion>

  <Accordion title="Wanneer het JSON-formaat geschikt is">
    * Wanneer je veel UI-teksten hebt en het bedenken van sleutels lastig is
    * Wanneer je Engels direct in de templates schrijft en andere talen via vertaalbestanden afhandelt
    * Bij applicaties waar internationalisatie later is toegevoegd

    ```blade theme={null}
    {{-- Schrijf Engels direct in de Blade-template --}}
    {{ __('Welcome to our application!') }}
    ```
  </Accordion>
</AccordionGroup>

## Vertaalstrings ophalen

### De `__()`-helper

De meestgebruikte manier. Bij PHP-bestanden geef je de sleutel op in het formaat "bestandsnaam.sleutel".

```php theme={null}
// PHP-bestand: de sleutel 'welcome' in lang/nl/messages.php
echo __('messages.welcome');
// => Welkom bij de applicatie!

// JSON-formaat: geef als sleutel de bronstring op
echo __('I love programming.');
// => Ik ben dol op programmeren.
```

Bestaat de vertaalstring niet, dan wordt de opgegeven sleutel zelf teruggegeven.

```php theme={null}
echo __('messages.not_exists');
// => messages.not_exists (de sleutel wordt als zodanig teruggegeven)
```

### Gebruik in Blade-templates

In Blade-templates gebruik je `{{ __() }}`.

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

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

{{-- @lang-directive (afgeraden; behouden voor achterwaartse compatibiliteit) --}}
@lang('messages.welcome')
```

<Tip>
  De `@lang`-directive wordt afgeraden. Tegenwoordig wordt aanbevolen om `{{ __() }}` te gebruiken.
</Tip>

## Placeholders

Je kunt placeholders in de vorm `:naam` in vertaalstrings opnemen.

```php theme={null}
// lang/nl/messages.php
return [
    'welcome' => 'Welkom, :name!',
    'greet'   => 'Hallo, :Name!',   // Eerste letter als hoofdletter
    'shout'   => 'HEY :NAME!',      // Volledig in hoofdletters
];
```

Aan het tweede argument van `__()` geef je een array met vervangwaarden door.

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

echo __('messages.greet', ['name' => 'taro']);
// => Hallo, Taro! (Name krijgt een beginhoofdletter)

echo __('messages.shout', ['name' => 'taro']);
// => HEY TARO! (NAME wordt volledig in hoofdletters)
```

Dit werkt in Blade-templates op dezelfde manier.

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

## Meervoudsvormen

De regels voor meervoudsvormen verschillen per taal. Met het `|`-teken schakelt Laravel tussen enkelvoud en meervoud.

### Eenvoudige meervoudsvormen

```php theme={null}
// lang/nl/messages.php
return [
    'apples' => 'Er is één appel|Er zijn meerdere appels',
];
```

In JSON-formaat definieer je dit op dezelfde manier.

```json theme={null}
{
    "There is one apple|There are many apples": "Er is één appel|Er zijn meerdere appels"
}
```

Met de functie `trans_choice()` geef je de hoeveelheid door.

```php theme={null}
echo trans_choice('messages.apples', 1);
// => Er is één appel

echo trans_choice('messages.apples', 5);
// => Er zijn meerdere appels
```

### Meervoudsvormen met bereiken

Je kunt gedetailleerdere bereiken opgeven.

```php theme={null}
'apples' => '{0} Geen appels|[1,19] Een paar appels|[20,*] Veel appels',
```

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

echo trans_choice('messages.apples', 10);
// => Een paar appels

echo trans_choice('messages.apples', 50);
// => Veel appels
```

### Placeholders in meervoudsvormen

Met `:count` toon je de hoeveelheid. Aan het derde argument geef je extra vervangwaarden door.

```php theme={null}
// lang/nl/messages.php
return [
    'minutes_ago' => '{1} :value minuut geleden|[2,*] :value minuten geleden',
    'items'       => 'Er zijn :count items',
];
```

```php theme={null}
echo trans_choice('messages.minutes_ago', 5, ['value' => 5]);
// => 5 minuten geleden

echo trans_choice('messages.items', 3);
// => Er zijn 3 items
```

## Taalbestanden van pakketten overschrijven

Wanneer een pakket van derden eigen taalbestanden heeft, kun je die overschrijven door een gelijknamig bestand te plaatsen in `lang/vendor/{pakketnaam}/{taalcode}/`.

Bijvoorbeeld om de Engelse meldingen van het pakket `skyrim/hearthfire` aan te passen:

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

```php theme={null}
// lang/vendor/hearthfire/en/messages.php
return [
    'welcome' => 'Aangepaste melding',
    // Definieer alleen de sleutels die je wilt overschrijven. De overige sleutels worden uit het oorspronkelijke bestand geladen
];
```

## Praktijkvoorbeeld: middleware voor het wisselen tussen Japans en Engels

Een voorbeeldimplementatie van middleware die de locale automatisch wisselt op basis van het URL-pad, de sessie of gebruikersinstellingen.

<Steps>
  <Step title="Maak de middleware aan">
    ```shell theme={null}
    php artisan make:middleware SetLocale
    ```
  </Step>

  <Step title="Implementeer de middleware">
    ```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
        {
            // Lijst met ondersteunde locales
            $supportedLocales = ['nl', 'en'];

            // Gebruik de locale uit de sessie als die is opgeslagen
            $locale = $request->session()->get('locale');

            // Staat er niets in de sessie, kijk dan naar de Accept-Language van de browser
            if (! $locale) {
                $browserLocale = substr($request->getPreferredLanguage($supportedLocales) ?? 'nl', 0, 2);
                $locale = in_array($browserLocale, $supportedLocales) ? $browserLocale : 'nl';
            }

            App::setLocale($locale);

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

  <Step title="Registreer de middleware">
    Registreer de middleware in `bootstrap/app.php`.

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

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

  <Step title="Voeg een route toe om de locale te wisselen">
    ```php theme={null}
    // routes/web.php
    Route::post('/locale/{locale}', function (string $locale) {
        if (! in_array($locale, ['nl', 'en'])) {
            abort(400);
        }

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

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

  <Step title="Voeg wisselknoppen toe aan de Blade-template">
    ```blade theme={null}
    <div>
        <form method="POST" action="{{ route('locale.switch', 'nl') }}">
            @csrf
            <button type="submit">Nederlands</button>
        </form>

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

### Voorbeeld van een vertaalbestandsstructuur

```text theme={null}
lang/
├── nl.json          # JSON-formaat (UI-teksten)
├── en.json
├── nl/
│   └── validation.php   # PHP-bestand (validatie)
└── en/
    └── validation.php
```

```json theme={null}
// lang/nl.json
{
    "Dashboard": "Dashboard",
    "Login": "Inloggen",
    "Logout": "Uitloggen",
    "Welcome, :name!": "Welkom, :name!",
    "Save": "Opslaan",
    "Cancel": "Annuleren",
    "Are you sure?": "Weet je het zeker?"
}
```

```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>
```

## Samenvatting

<AccordionGroup>
  <Accordion title="Manieren om vertaalstrings te definiëren">
    | Methode     | Bestandspad            | Voorbeeld van een sleutel | Ophalen                  |
    | ----------- | ---------------------- | ------------------------- | ------------------------ |
    | PHP-bestand | `lang/ja/messages.php` | `'welcome' => '...'`      | `__('messages.welcome')` |
    | JSON        | `lang/ja.json`         | `"Welcome": "..."`        | `__('Welcome')`          |
  </Accordion>

  <Accordion title="Veelgebruikte functies en facades">
    | Functie/methode               | Doel                                      |
    | ----------------------------- | ----------------------------------------- |
    | `__('key')`                   | Helper om een vertaalstring op te halen   |
    | `trans('key')`                | Helper gelijkwaardig aan `__()`           |
    | `trans_choice('key', $count)` | Vertaalstring met meervoudsvormen ophalen |
    | `App::setLocale('ja')`        | De locale per request wijzigen            |
    | `App::currentLocale()`        | De huidige locale ophalen                 |
    | `App::isLocale('ja')`         | De huidige locale controleren             |
  </Accordion>

  <Accordion title="Gebruik in Blade">
    ```blade theme={null}
    {{-- Basis --}}
    {{ __('messages.welcome') }}

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

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