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

# Lokalisierung

> Erläutert, wie Sie mit Laravels Mehrsprachigkeits-Funktionen Übersetzungen in PHP- und JSON-Dateien verwalten.

## Was ist Lokalisierung?

Die Lokalisierung von Laravel stellt einen bequemen Mechanismus bereit, um Übersetzungen für unterschiedliche Sprachen abzurufen.
Sie unterstützt mehrsprachige Anwendungen.

Es gibt zwei Wege, Übersetzungen zu verwalten:

| Vorgehen         | Eigenschaften                                                                                                                                     |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **PHP-Dateien**  | Schlüssel-Wert-Arrays wie `lang/ja/messages.php`. Ideal, wenn Übersetzungen z. B. für Validierungsfehler nach Feature strukturiert werden sollen. |
| **JSON-Dateien** | Übersetzungen direkt als Schlüssel in `lang/ja.json`. Empfohlen für Anwendungen mit vielen Übersetzungen.                                         |

<Info>
  Neue Laravel-Anwendungen enthalten kein Verzeichnis `lang`. Um es anzulegen, veröffentlichen Sie es mit dem Artisan-Befehl `lang:publish`.
</Info>

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

## Locale konfigurieren

### Standard-Locale

Die Standardsprache legen Sie in `config/app.php` über `locale` fest.
Üblich ist die Steuerung per Umgebungsvariable `APP_LOCALE` in der `.env`.

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

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

`fallback_locale` ist die Ausweichsprache, falls keine Übersetzung für die aktuelle Sprache existiert.

### Locale zur Laufzeit ändern

Mit `App::setLocale()` können Sie die Locale pro Request ändern.

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

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

    App::setLocale($locale);

    // ...
});
```

### Aktuelle Locale abfragen

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

$locale = App::currentLocale();

if (App::isLocale('de')) {
    // Ausführung, wenn die aktuelle Sprache Deutsch ist
}
```

## Sprachdateien anlegen

### PHP-Datei

Legen Sie PHP-Dateien im Verzeichnis `lang/{Sprachcode}/` an. Sie liefern ein Schlüssel-Wert-Array zurück.

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

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

// lang/de/messages.php

return [
    'welcome' => 'Willkommen in der Anwendung!',
    'goodbye' => 'Bis bald!',
];
```

<Warning>
  Für Sprachen mit regionalen Varianten verwenden Sie ISO-15897-konforme Verzeichnisnamen, z. B. `en_GB` statt `en-gb`.
</Warning>

### JSON-Datei

Bei vielen Übersetzungen empfiehlt sich das JSON-Format.
Legen Sie im Verzeichnis `lang/` eine JSON-Datei pro Sprachcode an.

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

Die Standard-Übersetzung (z. B. Englisch) dient als Schlüssel.

```json theme={null}
{
    "Welcome to our application!": "Willkommen in unserer Anwendung!",
    "I love programming.": "Ich programmiere leidenschaftlich gern.",
    "Logout": "Abmelden",
    "Dashboard": "Dashboard"
}
```

<Tip>
  Da der englische Satz selbst als Schlüssel dient, funktioniert die englische Ausgabe automatisch. In Sprachen ohne eigene Übersetzungsdatei wird der Schlüssel (das englische Original) unverändert angezeigt.
</Tip>

### Wann welches Format?

<AccordionGroup>
  <Accordion title="Wann sich PHP-Dateien eignen">
    * Wenn Sie Nachrichten z. B. für Validierungsfehler nach Feature strukturieren möchten
    * Wenn Sie Laravels eingebaute Übersetzungen (`validation.php`, `auth.php` usw.) überschreiben
    * Wenn Sie eine hierarchische Schlüsselverwaltung benötigen

    ```php theme={null}
    // lang/de/validation.php
    return [
        'required' => 'Das Feld :attribute ist erforderlich.',
        'email' => 'Das Feld :attribute muss eine gültige E-Mail-Adresse sein.',
    ];
    ```
  </Accordion>

  <Accordion title="Wann sich JSON eignet">
    * Wenn viele UI-Texte vorkommen und das Ausdenken von Schlüsseln lästig wird
    * Wenn Sie Templates direkt auf Englisch schreiben und andere Sprachen per Übersetzungsdatei ergänzen
    * Wenn Sie Internationalisierung nachträglich einführen

    ```blade theme={null}
    {{-- Englisch direkt im Blade-Template --}}
    {{ __('Welcome to our application!') }}
    ```
  </Accordion>
</AccordionGroup>

## Übersetzungen abrufen

### Helper `__()`

Am gebräuchlichsten. Bei PHP-Dateien schreiben Sie „Dateiname.Schlüssel".

```php theme={null}
// PHP-Datei: Schlüssel 'welcome' in lang/de/messages.php
echo __('messages.welcome');
// => Willkommen in der Anwendung!

// JSON: Übersetzungsschlüssel wird direkt übergeben
echo __('I love programming.');
// => Ich programmiere leidenschaftlich gern.
```

Ist keine Übersetzung vorhanden, wird der Schlüssel unverändert zurückgegeben.

```php theme={null}
echo __('messages.not_exists');
// => messages.not_exists (Schlüssel wird 1:1 zurückgegeben)
```

### Verwendung in Blade-Templates

In Blade-Templates verwenden Sie `{{ __() }}`.

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

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

{{-- @lang-Direktive (nicht mehr empfohlen; nur zur Rückwärtskompatibilität) --}}
@lang('messages.welcome')
```

<Tip>
  Die Direktive `@lang` gilt als veraltet. Aktuell wird `{{ __() }}` empfohlen.
</Tip>

## Platzhalter

In Übersetzungen können Sie Platzhalter im Format `:name` verwenden.

```php theme={null}
// lang/de/messages.php
return [
    'welcome' => 'Willkommen, :name!',
    'greet'   => 'Hallo, :Name!',   // Anfangsbuchstabe groß
    'shout'   => 'HEY :NAME!',      // Komplett in Großbuchstaben
];
```

Das zweite Argument von `__()` enthält die Ersetzungswerte.

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

echo __('messages.greet', ['name' => 'taro']);
// => Hallo, Taro! (Name mit großem Anfangsbuchstaben)

echo __('messages.shout', ['name' => 'taro']);
// => HEY TARO! (NAME komplett großgeschrieben)
```

In Blade-Templates funktioniert das genauso.

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

## Pluralformen

Die Pluralregeln unterscheiden sich je nach Sprache. In Laravel trennen Sie Singular und Plural mit `|`.

### Einfacher Plural

```php theme={null}
// lang/de/messages.php
return [
    'apples' => 'Es gibt einen Apfel|Es gibt mehrere Äpfel',
];
```

Auch in JSON möglich:

```json theme={null}
{
    "There is one apple|There are many apples": "Es gibt einen Apfel|Es gibt mehrere Äpfel"
}
```

Mit `trans_choice()` übergeben Sie die Anzahl.

```php theme={null}
echo trans_choice('messages.apples', 1);
// => Es gibt einen Apfel

echo trans_choice('messages.apples', 5);
// => Es gibt mehrere Äpfel
```

### Pluralformen mit Bereich

Detailliertere Bereichsangaben sind möglich.

```php theme={null}
'apples' => '{0} Keine Äpfel|[1,19] Ein paar Äpfel|[20,*] Viele Äpfel',
```

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

echo trans_choice('messages.apples', 10);
// => Ein paar Äpfel

echo trans_choice('messages.apples', 50);
// => Viele Äpfel
```

### Platzhalter in Pluralformen

Mit `:count` geben Sie die Anzahl aus. Zusätzliche Werte übergeben Sie im dritten Argument.

```php theme={null}
// lang/de/messages.php
return [
    'minutes_ago' => '{1} vor :value Minute|[2,*] vor :value Minuten',
    'items'       => ':count Artikel vorhanden',
];
```

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

echo trans_choice('messages.items', 3);
// => 3 Artikel vorhanden
```

## Sprachdateien von Paketen überschreiben

Für Sprachdateien von Drittanbieter-Paketen können Sie in `lang/vendor/{Paketname}/{Sprachcode}/` gleichnamige Dateien ablegen, um Übersetzungen zu überschreiben.

Beispiel: englische Nachrichten des Pakets `skyrim/hearthfire` anpassen.

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

```php theme={null}
// lang/vendor/hearthfire/en/messages.php
return [
    'welcome' => 'Angepasste Nachricht',
    // Nur die Schlüssel definieren, die überschrieben werden. Alle übrigen kommen aus der Originaldatei.
];
```

## Praxisbeispiel: Locale-Umschaltung per Middleware

Beispiel einer Middleware, die die Locale anhand von URL, Session oder Nutzerpräferenz umschaltet.

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

  <Step title="Middleware implementieren">
    ```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
        {
            // Unterstützte Sprachen
            $supportedLocales = ['de', 'en'];

            // Locale aus der Session verwenden, falls vorhanden
            $locale = $request->session()->get('locale');

            // Sonst Accept-Language des Browsers heranziehen
            if (! $locale) {
                $browserLocale = substr($request->getPreferredLanguage($supportedLocales) ?? 'de', 0, 2);
                $locale = in_array($browserLocale, $supportedLocales) ? $browserLocale : 'de';
            }

            App::setLocale($locale);

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

  <Step title="Middleware registrieren">
    Registrieren Sie die Middleware in `bootstrap/app.php`.

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

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

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

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

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

  <Step title="Buttons im Blade-Template">
    ```blade theme={null}
    <div>
        <form method="POST" action="{{ route('locale.switch', 'de') }}">
            @csrf
            <button type="submit">Deutsch</button>
        </form>

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

### Beispielhafter Aufbau der Sprachdateien

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

```json theme={null}
// lang/de.json
{
    "Dashboard": "Dashboard",
    "Login": "Anmelden",
    "Logout": "Abmelden",
    "Welcome, :name!": "Willkommen, :name!",
    "Save": "Speichern",
    "Cancel": "Abbrechen",
    "Are you sure?": "Sind Sie sicher?"
}
```

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

## Zusammenfassung

<AccordionGroup>
  <Accordion title="Wie werden Übersetzungen definiert?">
    | Format    | Dateipfad              | Beispielschlüssel    | Abruf                    |
    | --------- | ---------------------- | -------------------- | ------------------------ |
    | PHP-Datei | `lang/de/messages.php` | `'welcome' => '...'` | `__('messages.welcome')` |
    | JSON      | `lang/de.json`         | `"Welcome": "..."`   | `__('Welcome')`          |
  </Accordion>

  <Accordion title="Häufig genutzte Funktionen und Facades">
    | Funktion/Methode              | Zweck                        |
    | ----------------------------- | ---------------------------- |
    | `__('key')`                   | Übersetzung abrufen (Helfer) |
    | `trans('key')`                | Alternativhelfer zu `__()`   |
    | `trans_choice('key', $count)` | Übersetzung mit Pluralformen |
    | `App::setLocale('de')`        | Locale pro Request setzen    |
    | `App::currentLocale()`        | Aktuelle Locale abfragen     |
    | `App::isLocale('de')`         | Aktuelle Locale prüfen       |
  </Accordion>

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

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

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