Latte: ¿cómo funciona el sistema de tipos?

hace 5 años por David Grudl  

El sistema de tipos. Un asunto clave para el desarrollo de aplicaciones robustas, en el que PHP ha ganado una gran ventaja sobre lenguajes dinámicos como Python, Ruby o JavaScript. El framework Nette ha guiado a los programadores hacia la programación tipada y estricta desde el principio. Latte 2.7 introdujo el soporte de tipos también en las plantillas.

Gracias a que sabemos qué tipo de dato u objeto hay en cada variable, puede:

  • El IDE autocompletar correctamente
  • El análisis estático detectar errores

Dos puntos que aumentan fundamentalmente la calidad y la comodidad del desarrollo.

¿Cómo declarar tipos en el lado de PHP?

Pasaremos los datos a la plantilla como un objeto de una clase que define todas las variables y sus tipos. Utilizando las nuevas características de PHP 7.4, podría verse así:

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);

Aclaración: gracias a las nuevas características de PHP 8, el ejemplo se puede escribir de forma aún más interesante así:

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,
));

¿Cómo declarar tipos en la plantilla?

Ahora podemos vincular la clase mencionada con la plantilla. Basta con indicar al principio:

{templateType MailTemplate}

Y con esto hemos definido que en la plantilla habrá un cuarteto de variables $lang, $address, $subject y $price incluyendo los tipos correspondientes.

Una alternativa es definir los tipos de variables individuales directamente en la plantilla, es decir, sin crear una clase. Para esto sirve la etiqueta {varType}:

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

Por supuesto, se pueden combinar ambos. Crear una clase, porque así aseguramos el autocompletado en el lado del presenter, vincularla con la plantilla mediante {templateType} y para otras variables locales en bloques, etc., usar {varType}. Lo cual podemos entender como análogo a /** @var type $variable */, que es un comentario con el que a veces instruimos al IDE o al analizador estático en el código PHP.

Recientemente, también se puede indicar el tipo en las etiquetas {var}, {default} o {define}:

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

Nota: por razones históricas, era posible escribir variables en las etiquetas {var} y {default} sin el dólar inicial (y con una flecha en lugar de un signo igual). Dado que esto crea ambigüedad sobre si se trata de un tipo o una variable, esta sintaxis está prohibida y Latte le advertirá si la usa. Una forma sencilla de buscar en sus plantillas si tiene esta sintaxis antigua es buscar las expresiones regulares /\{(var|default) [^$]/ y /\{(var|default) [^}]*=>/.

¿Cómo ahorrar trabajo?

¿Cuál es la forma más fácil de escribir una clase de plantilla o etiquetas {varType}? Deje que se generen. Precisamente para eso existen el par de etiquetas {templatePrint} y {varPrint}.

Si coloca alguna de estas etiquetas en la plantilla, en lugar del renderizado normal, se mostrará una propuesta de código de la clase o una lista de etiquetas {varPrint} respectivamente. Luego, basta con marcar el código con un clic y copiarlo al proyecto.

Parte de nette/application 3.1 (en versión beta) es una etiqueta {templatePrint} sobrecargada que genera código mejor adaptado para los presenters.

La etiqueta {varPrint} lista las variables locales que no son parámetros de la plantilla. Si quiere listar todas las variables, use {varPrint all}.

Autocompletado en el IDE

La última versión del plugin Latte para PhpStorm puede utilizar las etiquetas mencionadas anteriormente y luego autocompletar basándose en los tipos. El plugin también conoce los tipos de variables estándar como $user, $presenter, $basePath, etc.

Análisis estático

El objetivo es que todos los tipos declarados también se puedan utilizar para el análisis estático. Para que, por ejemplo, usando PHPStan sea posible verificar las plantillas tan fácilmente como otros archivos PHP.

Estamos trabajando en esto y lo verá en alguna de las próximas versiones de Latte.