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

# Estensioni Blade di un pacchetto e cache di compilazione

> Analisi del BladeCompiler di Laravel 13: registrazione di direttive e istruzioni condizionali personalizzate, separazione tra compilazione ed esecuzione e verifica della cache delle view durante l'aggiornamento di un pacchetto.

Per offrire una sintassi Blade da un pacchetto, tieni separati **il processo che trasforma il template in PHP** e **il processo che esegue il PHP generato**. Se incorpori i valori di configurazione correnti al momento della compilazione, le view in cache possono continuare a mostrare valori obsoleti.

Questa pagina fa riferimento alla documentazione ufficiale di Laravel `13.x` e all'implementazione del Framework `v13.37.0`, e approfondisce le [basi dello sviluppo di pacchetti](/it/advanced/package-development). Per la sintassi ordinaria dei template consulta [Blade](/it/blade); per i namespace e la pubblicazione delle view consulta [Sovrascrivere e aggiornare le view di un pacchetto](/it/advanced/package-views).

## Distinguere registrazione, compilazione ed esecuzione

La callback passata a `Blade::directive()` non restituisce il valore da mostrare, ma **una stringa con il codice PHP da generare**. Anche l'argomento `$expression` non è un valore già valutato, bensì l'espressione PHP scritta nel template.

```mermaid theme={null}
flowchart TD
    A["Registrazione delle estensioni nel boot del provider"] --> B["Rendering della view"]
    B --> C{"Serve la compilazione?"}
    C -->|Sì| D["La callback della direttiva<br>genera il codice PHP"]
    D --> E["Salvataggio del risultato compilato"]
    C -->|No| F["Uso del PHP già salvato"]
    E --> G["Esecuzione del PHP e generazione dell'HTML"]
    F --> G
    G --> H["Lettura di configurazione e argomenti a runtime"]
```

| API | Ruolo della callback registrata | Quando viene eseguita |
| - | - | - |
| `Blade::directive()` | Genera una stringa di codice PHP | Quando viene compilata la direttiva interessata |
| `Blade::if()` | Valuta la condizione | Quando il PHP generato chiama `Blade::check()` |

Anche `view:cache` esegue la compilazione. Progetta le callback di generazione delle direttive in modo che non recuperino l'utente corrente, non scrivano sul database e non chiamino API esterne.

## Registrare con nomi specifici del pacchetto

Come esempio, forniamo `@acmeCourierLabel($code)`, che mostra l'etichetta configurata davanti al codice di spedizione. Si presuppone che il PSR-4 di Composer associ `Acme\Courier\` a `src/` e che il provider sia registrato tramite [rilevamento automatico](/it/advanced/package-discovery) o manualmente.

```php src/CourierServiceProvider.php theme={null}
<?php

namespace Acme\Courier;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Blade::directive('acmeCourierLabel', function (string $expression): string {
            return "<?php echo e((string) config('courier.label', 'Tracking').': '.({$expression})); ?>";
        });

        Blade::if('acmeCourierEnabled', function (): bool {
            return (bool) config('courier.enabled', false);
        });
    }
}
```

In questo esempio il contratto di configurazione prevede che `courier.label` sia una stringa e `courier.enabled` un booleano. Per la distribuzione e il merge dei file di configurazione consulta [Merge e cache della configurazione dei pacchetti](/it/advanced/package-config-merging).

Esegui la registrazione nel normale `boot()` del provider, senza racchiuderla in una condizione `runningInConsole()`. La stessa estensione serve sia per il rendering via HTTP sia per `view:cache` di Artisan. Evita anche di rendere differito un provider che registra solo estensioni Blade, perché non verrebbe avviato finché non si risolve un altro servizio.

### Gli argomenti arrivano come espressioni, non come valori

```blade theme={null}
@acmeCourierLabel($code)
```

Con questo template, la callback riceve la stringa `$code`. Il PHP generato ha la forma seguente.

```php theme={null}
<?php echo e((string) config('courier.label', 'Tracking').': '.($code)); ?>
```

`config()` e `$code` vengono valutati nel momento in cui questo PHP viene eseguito. È diverso da un'implementazione in cui la callback stessa legge `config()` e restituisce una stringa fissa.

Il metodo `callCustomDirective()` esaminato rimuove le parentesi tonde esterne, applica trim all'espressione e la passa alla callback. Non converte l'argomento in un valore PHP né lo suddivide in argomenti separati. Questo esempio viene esposto come **una sintassi che accetta un'unica espressione obbligatoria**.

Se devi gestire più argomenti, non limitarti a fare `explode()` sulle virgole: le virgole possono comparire anche all'interno di array, chiamate di metodo e stringhe letterali. Se vuoi gestire attributi o HTML complesso, fornire la funzionalità come [componente Blade](/it/blade) rende più facile separare le responsabilità.

<Warning>
  Le espressioni del template sono codice PHP scritto da sviluppatori fidati. Non costruire il sorgente di un template a partire dall'input degli utenti. Inoltre, l'`echo` di una direttiva personalizzata non riceve automaticamente l'escape del normale `{{ }}`. In questo esempio il PHP generato chiama esplicitamente `e()`.
</Warning>

### Anche i conflitti di nome sono un problema di compatibilità

`directive()` salva l'handler in un array usando il nome come chiave. Con lo stesso nome sovrascrive la registrazione precedente, e `compileStatement()` sceglie le direttive personalizzate prima dei metodi di conversione predefiniti. Anche i test ufficiali includono un caso in cui una registrazione personalizzata sovrascrive `foreach`.

Evita nomi generici come `label` o `enabled` e i nomi predefiniti, e aggiungi un prefisso specifico del pacchetto. Tratta i nomi e gli argomenti che gli utenti usano nei template come API pubblica e, quando li modifichi, fornisci una procedura di migrazione.

## Valutare le condizioni a runtime con Blade::if

La condizione registrata nel provider precedente si può usare così.

```blade theme={null}
@acmeCourierEnabled
    @acmeCourierLabel($code)
@else
    Il tracciamento delle spedizioni è disattivato.
@endacmeCourierEnabled
```

`Blade::if()` salva la callback della condizione e registra le direttive di apertura, `unless`, `else` e chiusura. In questo esempio la parte di apertura viene convertita nel PHP seguente.

```php theme={null}
<?php if (\Illuminate\Support\Facades\Blade::check('acmeCourierEnabled')): ?>
```

La callback che controlla la configurazione viene chiamata da `check()` a runtime. Non si tratta di un processo che fissa il risultato true o false al momento della compilazione. Anche i processi HTTP che usano view compilate devono avere registrata la callback della condizione.

Questa sintassi serve a cambiare ciò che viene mostrato, non ad autorizzare le operazioni di spedizione. Applica il controllo degli accessi anche nelle route o nelle operazioni stesse.

## L'aggiornamento di un pacchetto non rigenera sempre le view

Il metodo `Compiler::isExpired()` esaminato controlla l'esistenza della cache e, a seconda della configurazione, gli orari di modifica della view sorgente e del file compilato. **Non tiene traccia, come file dipendenti, delle modifiche alle direttive scritte nel provider.**

| Modifica | Impatto sul PHP compilato |
| - | - |
| Cambiare il codice restituito da `directive()` | Il vecchio PHP resta, quindi serve ricompilare |
| Cambiare solo la logica della callback della condizione di `Blade::if()` | Il `check()` già generato può chiamare la nuova logica, ma il nuovo codice deve essere caricato |
| Cambiare il nome della direttiva o il contratto degli argomenti | Servono la modifica dei template degli utenti e la ricompilazione |
| View già pubblicate nell'applicazione | Aggiornare solo le view del pacchetto non aggiorna le copie pubblicate |

Anche la documentazione ufficiale indica di eliminare la cache con `view:clear` dopo aver modificato la logica di una direttiva. Eseguilo nel processo di deploy dell'applicazione che usa il pacchetto, dopo aver allineato il pacchetto aggiornato e le view dell'utente.

```bash theme={null}
php artisan view:clear
php artisan view:cache
```

Esegui `view:cache` quando vuoi precompilare le view in produzione. Non svuotare la cache a ogni `boot()` del pacchetto e non modificare senza permesso il processo di deploy dell'applicazione durante l'installazione. Anche l'aggiornamento della cache di configurazione e il ricaricamento dei processi residenti devono seguire la normale procedura di deploy dell'ambiente dell'utente.

## Verificare separatamente il risultato della compilazione e del rendering

Per prima cosa, verifica il PHP generato in un'applicazione Laravel di test in cui è registrato il provider precedente. Il metodo seguente va aggiunto a un test Feature che estende `Tests\TestCase`.

```php theme={null}
public function test_label_directive_compiles_to_runtime_lookup(): void
{
    $compiled = \Illuminate\Support\Facades\Blade::compileString(
        '@acmeCourierLabel($code)',
    );

    $this->assertSame(
        "<?php echo e((string) config('courier.label', 'Tracking').': '.(\$code)); ?>",
        $compiled,
    );
}
```

Questo test verifica il contratto di generazione del PHP, ma non l'escape a runtime né i rami condizionali. In un pacchetto reale aggiungi anche verifiche sul rendering delle view e sugli aggiornamenti.

| Caso da verificare | Risultato atteso |
| - | - |
| Passare al codice di spedizione caratteri interpretati come HTML | Vengono sottoposti a escape dall'`e()` generato |
| Usare la stessa view compilata e cambiare l'etichetta configurata prima del rendering | Il rendering successivo mostra il nuovo valore di configurazione |
| Eseguire il rendering con `courier.enabled` a true e a false | Viene mostrato solo il ramo corrispondente |
| Avviare una nuova applicazione dopo `view:cache` | L'estensione è registrata e il risultato è lo stesso che senza precompilazione |
| Modificare il codice generato dalla direttiva ed eseguire il deploy | Dopo la ricreazione della cache viene usato il nuovo PHP |
| Aggiornare la versione di Laravel supportata | I test su codice generato, rendering e uso della cache passano tutti |

## Pagine correlate

<Columns cols={2}>
  <Card title="Sovrascrivere e aggiornare le view di un pacchetto" icon="eye" href="/it/advanced/package-views">
    Scopri l'ordine di ricerca dei namespace e come mantenere i template pubblicati.
  </Card>

  <Card title="Cache dei pacchetti e integrazione con optimize" icon="gears" href="/it/advanced/package-optimization">
    Scopri come integrare la creazione e l'eliminazione delle cache personalizzate nel processo di deploy.
  </Card>
</Columns>

## Fonti primarie consultate

* [Documentazione ufficiale di Laravel: Extending Blade e Custom if statements](https://github.com/laravel/docs/blob/12080c72699b99ec6573f7e79ff4834d9001b6bc/blade.md#extending-blade)
* [Documentazione ufficiale di Laravel: view e componenti dei pacchetti](https://github.com/laravel/docs/blob/12080c72699b99ec6573f7e79ff4834d9001b6bc/packages.md#views)
* [BladeCompiler: directive(), callCustomDirective(), compileStatement(), if() e check()](https://github.com/laravel/framework/blob/v13.37.0/src/Illuminate/View/Compilers/BladeCompiler.php)
* [Compiler: verifica della cache con isExpired()](https://github.com/laravel/framework/blob/v13.37.0/src/Illuminate/View/Compilers/Compiler.php)
* [BladeCustomTest: direttive personalizzate, condizioni e sovrascrittura della sintassi predefinita](https://github.com/laravel/framework/blob/v13.37.0/tests/View/Blade/BladeCustomTest.php)


## Related topics

- [Argomenti avanzati](/it/advanced/index.md)
- [Registrazione e cache dei listener di eventi di un pacchetto](/it/advanced/package-events.md)
- [Registrazione e cache delle route di un pacchetto](/it/advanced/package-routes.md)
- [Sovrascrivere e aggiornare le view di un pacchetto](/it/advanced/package-views.md)
- [Template Blade](/it/blade.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.