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

# Localizzazione

> Come gestire le stringhe tradotte in file PHP e JSON usando la funzionalità multilingua di Laravel.

## Cos'è la localizzazione

La localizzazione di Laravel offre un meccanismo comodo per ottenere stringhe tradotte in più lingue.
La usi per supportare più lingue nella tua applicazione.

Ci sono due modi per gestire le stringhe di traduzione.

| Modalità      | Caratteristiche                                                                                                               |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **File PHP**  | Array chiave-valore in `lang/it/messages.php`. Adatto per organizzare i messaggi per funzionalità (es. errori di validazione) |
| **File JSON** | Stringhe definite come chiave in `lang/it.json`. Consigliato per applicazioni con molte traduzioni                            |

<Info>
  Le applicazioni Laravel predefinite non includono la directory `lang`. Per personalizzare pubblicala con `lang:publish`.
</Info>

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

## Impostazione della locale

### Locale predefinita

La lingua predefinita si imposta in `locale` di `config/app.php`.
Di norma usi la variabile d'ambiente `APP_LOCALE` in `.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=it
APP_FALLBACK_LOCALE=en
```

`fallback_locale` è la lingua di fallback quando la stringa non esiste nella lingua richiesta.

### Cambio di locale a runtime

Con il metodo `setLocale()` della facade `App` cambi la locale per una singola richiesta.

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

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

    App::setLocale($locale);

    // ...
});
```

### Verificare la locale corrente

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

$locale = App::currentLocale();

if (App::isLocale('it')) {
    // Se è italiano
}
```

## Creazione dei file di traduzione

### Formato file PHP

Crea file PHP nella directory `lang/{codice}/`. Restituiscono un array associativo chiave-valore.

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

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

// lang/it/messages.php

return [
    'welcome' => 'Benvenuto nell\'applicazione!',
    'goodbye' => 'A presto!',
];
```

<Warning>
  Per le lingue con varianti regionali usa i codici ISO 15897. Ad esempio inglese britannico è `en_GB`, non `en-gb`.
</Warning>

### Formato JSON

Con molte stringhe da tradurre è consigliato il JSON.
Crea file JSON con il nome della lingua in `lang/`.

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

Le stringhe predefinite (di norma in inglese) diventano le chiavi.

```json theme={null}
{
    "Welcome to our application!": "Benvenuto nell'applicazione!",
    "I love programming.": "Adoro programmare.",
    "Logout": "Esci",
    "Dashboard": "Cruscotto"
}
```

<Tip>
  Nel formato JSON, il testo inglese è la chiave: la visualizzazione predefinita in inglese funziona automaticamente. Nelle lingue senza file di traduzione viene mostrata la chiave stessa (l'originale).
</Tip>

### Quando usare PHP o JSON

<AccordionGroup>
  <Accordion title="Quando conviene il formato PHP">
    * Quando vuoi organizzare per funzionalità (es. messaggi di validazione)
    * Quando sovrascrivi traduzioni integrate di Laravel (`validation.php`, `auth.php`, ecc.)
    * Quando serve una gestione gerarchica delle chiavi

    ```php theme={null}
    // lang/it/validation.php
    return [
        'required' => 'Il campo :attribute è obbligatorio.',
        'email' => 'Il campo :attribute deve essere un\'email valida.',
    ];
    ```
  </Accordion>

  <Accordion title="Quando conviene JSON">
    * Molte stringhe di UI, chiavi laboriose da pensare
    * Vuoi scrivere l'inglese direttamente nei template e tradurre solo le altre lingue
    * Internazionalizzazione aggiunta a posteriori

    ```blade theme={null}
    {{-- Scrivi l'inglese direttamente in Blade --}}
    {{ __('Welcome to our application!') }}
    ```
  </Accordion>
</AccordionGroup>

## Recupero delle traduzioni

### Helper `__()`

Il modo più usato. In formato PHP usa `nomefile.chiave`.

```php theme={null}
// Formato PHP: chiave 'welcome' in lang/it/messages.php
echo __('messages.welcome');
// => Benvenuto nell'applicazione!

// Formato JSON: usa direttamente il testo originale come chiave
echo __('I love programming.');
// => Adoro programmare.
```

Se la stringa non esiste viene restituita la chiave stessa.

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

### Uso in Blade

Nei template Blade usa `{{ __() }}`.

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

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

{{-- Direttiva @lang (deprecata, mantenuta per compatibilità) --}}
@lang('messages.welcome')
```

<Tip>
  La direttiva `@lang` è deprecata. Oggi si consiglia `{{ __() }}`.
</Tip>

## Placeholder

Puoi inserire nei testi tradotti dei placeholder `:nome`.

```php theme={null}
// lang/it/messages.php
return [
    'welcome' => 'Benvenuto, :name!',
    'greet'   => 'Ciao, :Name!',  // Prima lettera maiuscola
    'shout'   => 'EHI :NAME!',    // Tutto maiuscolo
];
```

Passa un array di sostituzioni come secondo argomento a `__()`.

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

echo __('messages.greet', ['name' => 'mario']);
// => Ciao, Mario!

echo __('messages.shout', ['name' => 'mario']);
// => EHI MARIO!
```

Anche in Blade:

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

## Plurale

Le regole del plurale variano per lingua. Con `|` puoi separare singolare e plurale.

### Plurale di base

```php theme={null}
// lang/it/messages.php
return [
    'apples' => 'C\'è una mela|Ci sono molte mele',
];
```

Anche in JSON:

```json theme={null}
{
    "There is one apple|There are many apples": "C'è una mela|Ci sono molte mele"
}
```

Usa `trans_choice()` passando la quantità.

```php theme={null}
echo trans_choice('messages.apples', 1);
// => C'è una mela

echo trans_choice('messages.apples', 5);
// => Ci sono molte mele
```

### Plurale con range

Puoi indicare intervalli.

```php theme={null}
'apples' => '{0} Nessuna mela|[1,19] Alcune mele|[20,*] Tante mele',
```

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

echo trans_choice('messages.apples', 10);
// => Alcune mele

echo trans_choice('messages.apples', 50);
// => Tante mele
```

### Placeholder nei plurali

Usa `:count` per mostrare la quantità. Passa altri valori come terzo argomento.

```php theme={null}
// lang/it/messages.php
return [
    'minutes_ago' => '{1} :value minuto fa|[2,*] :value minuti fa',
    'items'       => 'Ci sono :count elementi',
];
```

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

echo trans_choice('messages.items', 3);
// => Ci sono 3 elementi
```

## Sovrascrivere i file di traduzione dei pacchetti

Se un pacchetto di terze parti ha propri file di traduzione, puoi sovrascriverlo posizionando file con lo stesso nome in `lang/vendor/{nome-pacchetto}/{codice}/`.

Ad esempio per personalizzare i messaggi inglesi di `skyrim/hearthfire`:

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

```php theme={null}
// lang/vendor/hearthfire/en/messages.php
return [
    'welcome' => 'Messaggio personalizzato',
    // Definisci solo le chiavi che vuoi sovrascrivere. Le altre restano dal file originale.
];
```

## Esempio pratico: middleware di switch italiano/inglese

Middleware che imposta la locale in base a sessione, preferenze utente o URL.

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

  <Step title="Implementa il 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
        {
            // Elenco delle locale supportate
            $supportedLocales = ['it', 'en'];

            // Se in sessione c'è una locale, usala
            $locale = $request->session()->get('locale');

            // Altrimenti usa Accept-Language del browser
            if (! $locale) {
                $browserLocale = substr($request->getPreferredLanguage($supportedLocales) ?? 'it', 0, 2);
                $locale = in_array($browserLocale, $supportedLocales) ? $browserLocale : 'it';
            }

            App::setLocale($locale);

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

  <Step title="Registra il middleware">
    Registralo in `bootstrap/app.php`.

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

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

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

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

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

  <Step title="Aggiungi i pulsanti nella vista Blade">
    ```blade theme={null}
    <div>
        <form method="POST" action="{{ route('locale.switch', 'it') }}">
            @csrf
            <button type="submit">Italiano</button>
        </form>

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

### Esempio di struttura dei file di traduzione

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

```json theme={null}
// lang/it.json
{
    "Dashboard": "Cruscotto",
    "Login": "Accedi",
    "Logout": "Esci",
    "Welcome, :name!": "Benvenuto, :name!",
    "Save": "Salva",
    "Cancel": "Annulla",
    "Are you sure?": "Sei sicuro?"
}
```

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

## Riepilogo

<AccordionGroup>
  <Accordion title="Come definire le traduzioni">
    | Modalità | File                   | Esempio di chiave    | Recupero                 |
    | -------- | ---------------------- | -------------------- | ------------------------ |
    | File PHP | `lang/it/messages.php` | `'welcome' => '...'` | `__('messages.welcome')` |
    | JSON     | `lang/it.json`         | `"Welcome": "..."`   | `__('Welcome')`          |
  </Accordion>

  <Accordion title="Funzioni e facade utili">
    | Funzione/metodo               | Uso                          |
    | ----------------------------- | ---------------------------- |
    | `__('key')`                   | Helper per stringhe tradotte |
    | `trans('key')`                | Equivalente di `__()`        |
    | `trans_choice('key', $count)` | Traduzione al plurale        |
    | `App::setLocale('it')`        | Cambia locale per richiesta  |
    | `App::currentLocale()`        | Locale corrente              |
    | `App::isLocale('it')`         | Verifica la locale           |
  </Accordion>

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

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

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


## Related topics

- [Eloquent Factory](/it/eloquent-factories.md)
