Latte: come usare il sistema di tipi?

5 anni fa Da David Grudl  

Il sistema di tipi è l'elemento principale per lo sviluppo di applicazioni robuste. I tipi in PHP hanno una superiorità rispetto ad altri linguaggi dinamici come Python, Ruby o JavaScript. Il framework Nette porta i programmatori a produrre codice tipizzato e rigoroso fin dall'inizio. Latte 2.7 ha portato il supporto dei tipi anche ai template.

Sapere quale sia il tipo di dato o di oggetto di ciascuna variabile permette all'IDE di

  • all'IDE di effettuare correttamente il completamento automatico
  • l'analisi statica per rilevare gli errori

Due punti che migliorano significativamente la qualità e la convenienza dello sviluppo.

Come dichiarare i tipi sul lato PHP?

Passeremo i dati al template come oggetto di una classe che definisce tutte le variabili e i loro tipi. Utilizzando le nuove caratteristiche di PHP 7.4, potrebbe essere così:

class MailTemplate
{
	public string $lang = 'cs';
	public Address $address;
	public string $subject;
	public ?float $price = null;
}

Uso:

$template = new MailTemplate;
$template->price = $this->getPrice();
...
$latte->render('mail.latte', $template);

Aggiunta: grazie alle nuove caratteristiche di PHP 8, l'esempio può essere scritto in modo più interessante come questo:

class MailTemplate
{
	public function __construct(
		public string $lang = 'cs',
		public Address $address,
		public string $subject,
		public ?float $price = null,
	) {}
}

$latte->render('mail.latte', new MailTemplate(
	lang: $this->lang,
	subject: $title,
	price: $this->getPrice(),
	address: $userAddress,
));

Come dichiarare i tipi in un template?

Ora possiamo associare la classe al template. Dobbiamo solo dichiararlo all'inizio:

{templateType MailTemplate}

Abbiamo così definito che il modello conterrà un quartetto di variabili $lang, $address, $subject e $price con i rispettivi tipi.

L'alternativa è definire i tipi di ogni variabile direttamente nel template, cioè senza creare una classe. A questo scopo si utilizza il tag {varType}:

{varType string $lang}
{varType Address $address}

Naturalmente, entrambe le opzioni possono essere combinate. Creare una classe, in modo da garantire il completamento dal lato del presentatore, collegarla al template usando {templateType} e usare {varType} per altre variabili locali nei blocchi, ecc. Questo può essere inteso come un'analogia /** @var type $variable */, che è un commento che a volte si usa nel codice PHP per istruire l'IDE o lo strumento di analisi statica.

Inoltre, il tipo può essere specificato in {var}, {default} o {define}:

{var Model\Page $page = $items['page']}
{define form, string $name}
	...
{/define}

Nota: per ragioni storiche, era possibile scrivere variabili nei tag {var} e {default} senza il segno di dollaro iniziale. Poiché ciò crea ambiguità se si tratta di un tipo o di una variabile, questa sintassi è deprecata e Latte vi avvertirà quando la usate.

Come si fa a semplificare il lavoro?

Come scrivere una classe template o {varType} nel modo più semplice possibile? Generarli. Questo è esattamente ciò che fanno i tag {templatePrint} e {varPrint}.

Se si inserisce uno di questi tag in un template, il codice della classe o del template viene visualizzato al posto del normale rendering. È sufficiente selezionare e copiare il codice nel progetto.

Nette/application 3.1 (beta) include un tag sovraccarico {templatePrint} che genera codice più adatto ai presentatori.

Il tag {varPrint} elenca le variabili locali che non sono parametri del modello. Se si desidera elencare tutte le variabili, utilizzare {varPrint all}.

Completamento del codice IDE

L'ultima versione del plugin PhpStorm Latte può sfruttare i tag di cui sopra e suggerire in base ai tipi. Il plugin conosce anche i tipi di variabili standard come $user, $presenter, $basePath, ecc.

Analisi statica

L'obiettivo finale è che tutti i tipi dichiarati possano essere usati anche per l'analisi statica. Per esempio, usare PHPStan per controllare i template con la stessa facilità degli altri file PHP.

Ci stiamo lavorando e lo vedremo in una delle prossime versioni di Latte.