Nette Documentation Preview

syntax
Sintaxis
********

.[perex]
La sintaxis de Latte nació de las necesidades prácticas de los diseñadores web. Buscábamos la sintaxis más amable posible, con la que se puedan escribir con elegancia construcciones que de otro modo son un auténtico reto. Al mismo tiempo, todas las expresiones se escriben exactamente igual que en PHP, así que no tiene que aprender un lenguaje nuevo. Simplemente aprovecha lo que ya sabe.

A continuación tiene una plantilla mínima que ilustra varios elementos básicos: etiquetas, n:atributos, comentarios y filtros.

```latte
{* esto es un comentario *}
<ul n:if=$items>                  {* n:if es un n:atributo *}
{foreach $items as $item}         {* etiqueta que representa un bucle foreach *}
	<li>{$item|capitalize}</li>   {* etiqueta que muestra una variable con un filtro *}
{/foreach}                        {* fin del bucle *}
</ul>
```

Veamos más de cerca estos elementos importantes y cómo pueden ayudarle a crear una plantilla estupenda.


Etiquetas
=========

Una plantilla contiene etiquetas que controlan su lógica (por ejemplo, bucles *foreach*) o imprimen expresiones. Para ambas cosas se usa un único delimitador `{ ... }`, así que, a diferencia de otros sistemas, no tiene que pensar qué delimitador usar en cada situación. Si al carácter `{` le sigue inmediatamente un espacio en blanco, unas comillas u otra `{` o `}`, Latte no lo considera el comienzo de una etiqueta, lo que le permite usar sin problemas construcciones de JavaScript, JSON o reglas CSS en sus plantillas.

Vea el [resumen de todas las etiquetas|tags]. Además, puede crear sus propias [etiquetas personalizadas|custom-tags]. También puede cambiar los delimitadores `{ }` o desactivarlos por completo (con `{syntax double}`, `{syntax off}` o el atributo `n:syntax`); vea [cambiar la sintaxis |tags#{syntax}].


Latte entiende PHP
==================

Dentro de las etiquetas puede usar las expresiones de PHP que ya conoce:

- variables
- cadenas (incluidas HEREDOC y NOWDOC), arrays, números, etc.
- [operadores |https://www.php.net/manual/en/language.operators.php]
- llamadas a funciones y métodos (que se pueden restringir con el [sandbox|sandbox])
- [match |https://www.php.net/manual/en/control-structures.match.php]
- [funciones flecha |https://www.php.net/manual/en/functions.arrow.php]
- [sintaxis callable de primera clase |https://www.php.net/manual/en/functions.first_class_callable_syntax.php]
- comentarios multilínea `/* ... */`
- etc.

Además, Latte enriquece la sintaxis de PHP con varias [extensiones cómodas |#Azúcar sintáctico].


n:atributos
===========

Toda etiqueta par, como `{if} … {/if}`, que opere sobre un único elemento HTML se puede reescribir en forma de n:atributo. Por ejemplo, el `{foreach}` del ejemplo introductorio también podría escribirse así:

```latte
<ul n:if=$items>
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>
```

La funcionalidad se aplica entonces al elemento HTML en el que está colocada:

```latte
{var $items = ['I', '♥', 'Latte']}

<p n:foreach="$items as $item">{$item}</p>
```

imprime:

```latte
<p>I</p>
<p>♥</p>
<p>Latte</p>
```

Con el prefijo `inner-` podemos modificar el comportamiento para que se aplique solo a la parte interior del elemento:

```latte
<div n:inner-foreach="$items as $item">
	<p>{$item}</p>
	<hr>
</div>
```

Imprime:

```latte
<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>
```

O bien, con el prefijo `tag-`, aplicamos la funcionalidad solo a las propias etiquetas HTML:

```latte
<p><a href={$url} n:tag-if="$url">Title</a></p>
```

Lo que imprime, según el valor de la variable `$url`:

```latte
{* cuando $url está vacía *}
<p>Title</p>

{* cuando $url contiene 'https://nette.org' *}
<p><a href="https://nette.org">Title</a></p>
```

Los n:atributos no son, sin embargo, solo un atajo para las etiquetas pares: existen también algunos n:atributos puros, por ejemplo el mejor amigo del programador [n:class|tags#n:class] o el prácticamente indispensable [n:href |application:creating-links#En la plantilla del presenter].

Además de la sintaxis con comillas `<div n:if="$foo">`, puede usar la sintaxis alternativa con llaves `<div n:if={$foo}>`. Su principal ventaja es que dentro de `{...}` puede usar libremente comillas simples y dobles:

```latte
<div n:if={str_contains($val, "foo")}> ... </div>
```


Atributos HTML inteligentes .{data-version:3.1.0}
=================================================

Latte hace increíblemente fácil trabajar con los atributos HTML estándar. Gestiona por usted los atributos booleanos como `checked`, elimina los atributos que contienen `null` y le permite componer los valores de `class` y `style` con arrays. Incluso serializa automáticamente los datos de los atributos `data-` a JSON.

```latte
{* null elimina el atributo *}
<div title={$title}>

{* el booleano controla la presencia de los atributos booleanos *}
<input type="checkbox" checked={$isChecked}>

{* los arrays funcionan en class *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* los arrays se codifican en JSON en los atributos data- *}
<div data-config={[theme: dark, version: 2]}>
```

Más información en el capítulo aparte [Atributos HTML inteligentes|html-attributes].


Filtros
=======

Vea el resumen de los [filtros estándar |filters].

Los filtros se escriben tras el símbolo de tubería (se admite un espacio delante):

```latte
<h1>{$heading|upper}</h1>
```

Los filtros se pueden encadenar y se aplican en orden de izquierda a derecha:

```latte
<h1>{$heading|lower|capitalize}</h1>
```

Los argumentos van tras el nombre del filtro después de dos puntos, y los siguientes se separan con comas; también funciona la llamada entre paréntesis:

```latte
<h1>{$heading|truncate:20,''}</h1>
<h1>{$heading|truncate(20, '')}</h1>
```

Los filtros también se pueden aplicar a una expresión:

```latte
{var $name = ($title|upper) . ($subtitle|lower)}
```

A un bloque:

```latte
<h1>{block |lower}{$heading}{/block}</h1>
```

O directamente a un valor (en combinación con la etiqueta [`{=expr}` |tags#Impresión]):

```latte
<h1>{='  Hello world  '|trim}</h1>
```

Si el valor puede ser `null` y quiere evitar que se aplique el filtro en ese caso, use el [filtro nullsafe |filters#Filtros nullsafe] `?|`:

```latte
<h1>{$heading?|upper}</h1>
```


Etiquetas HTML dinámicas .{data-version:3.0.9}
==============================================

Latte admite etiquetas HTML dinámicas, útiles cuando necesita flexibilidad en los nombres de las etiquetas:

```latte
<h{$level}>Heading</h{$level}>
```

Por ejemplo, el código anterior puede generar `<h1>Heading</h1>` o `<h2>Heading</h2>` según el valor de la variable `$level`. Las etiquetas HTML dinámicas en Latte deben ser siempre pares. Su alternativa es [n:tag |tags#n:tag].

Como Latte es un sistema de plantillas seguro, comprueba que el nombre de etiqueta resultante sea válido y no contenga valores indeseados o maliciosos. También se asegura de que el nombre de la etiqueta de cierre coincida siempre con el de la de apertura.


Comentarios
===========

Los comentarios se escriben así y no llegan a la salida:

```latte
{* esto es un comentario en Latte *}
```

Dentro de las etiquetas funcionan los comentarios de PHP:

```latte
{include 'file.info', /* value: 123 */}
```


Control del espacio en blanco
=============================

Latte trata el espacio en blanco de forma inteligente. Puede sangrar su código libremente para hacerlo legible y la salida sigue quedando limpia. Cuando una etiqueta de control aparece sola en una línea, se elimina de la salida toda la línea (la sangría y el salto de línea); esto no vale para las etiquetas que imprimen salida, como `{$var}`, `{=...}` o `{_...}`, que conservan su sangría y su salto de línea final:

```latte
<ul>
	{foreach $items as $item}
	<li>{$item}</li>
	{/foreach}
</ul>
```

Imprime:

```latte
<ul>
	<li>foo</li>
	<li>bar</li>
</ul>
```

¿Y si una etiqueta no está sola en la línea, sino junto a otro contenido? El espacio en blanco anterior a la etiqueta pertenece entonces al *interior* de la etiqueta:

```latte
<div>
	{if $foo}hello{/if}
</div>
```

La sangría está, de hecho, dentro del `{if}`: cuando `$foo` es falso, no se imprime nada, ni siquiera la sangría o una línea vacía. Cuando `$foo` es verdadero, la salida incluye naturalmente la sangría. Usted se limita a escribir plantillas bien estructuradas y la salida siempre queda limpia.

Para una salida aún más limpia puede activar la función [Dedent |develop#Dedent], que elimina además la sangría provocada por el anidamiento dentro de etiquetas pares como `{if}` o `{foreach}`.


Azúcar sintáctico
=================


Cadenas sin comillas
--------------------

En las cadenas sencillas se pueden omitir las comillas:

```latte
as in PHP:   {var $arr = ['hello', 'btn--default', '€']}

abbreviated: {var $arr = [hello, btn--default, €]}
```

Son cadenas sencillas las compuestas únicamente por letras, dígitos, guiones bajos, guiones y puntos. No pueden empezar por un dígito ni empezar o terminar con un guion. No pueden estar formadas solo por letras mayúsculas y guiones bajos, porque entonces se consideran constantes (por ejemplo, `PHP_VERSION`). Y no pueden coincidir con las palabras clave: `and`, `array`, `clone`, `default`, `false`, `in`, `instanceof`, `new`, `null`, `or`, `return`, `true`, `xor`.


Constantes
----------

Use el separador del espacio de nombres global para distinguir las constantes globales de las cadenas sencillas:

```latte
{if \PROJECT_ID === 1} ... {/if}
```

Esta notación es del todo válida en el propio PHP, donde la barra invertida indica que la constante está en el espacio de nombres global.


Operador ternario abreviado
---------------------------

Si el tercer valor del operador ternario está vacío, se puede omitir:

```latte
as in PHP:   {$stock ? 'In stock' : ''}

abbreviated: {$stock ? 'In stock'}
```


Notación moderna de claves en arrays
------------------------------------

Las claves de los arrays se pueden escribir de forma parecida a los parámetros nombrados al llamar a funciones:

```latte
as in PHP:   {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

modern:      {var $arr = [one: 'item 1', two: 'item 2']}
```


Filtros
-------

Los filtros se pueden usar sobre cualquier expresión; basta con encerrar toda la expresión entre paréntesis:

```latte
{var $content = ($text|truncate: 30|upper)}
```


Operador `in`
-------------

El operador `in` puede sustituir a la función `in_array()`. La comparación es siempre estricta:

```latte
{* como in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}
```


Una ventana a la historia
-------------------------

A lo largo de su historia, Latte introdujo varias formas de azúcar sintáctico que aparecieron en el propio PHP unos años más tarde. Por ejemplo, en Latte se podían escribir los arrays como `[1, 2, 3]` en lugar de `array(1, 2, 3)`, o usar el operador nullsafe `$obj?->foo`, mucho antes de que fuera posible en el propio PHP. Latte introdujo también el operador de expansión de arrays `(expand) $arr`, equivalente al actual operador `...$arr` de PHP.


Limitaciones de PHP en Latte
============================

En Latte solo se pueden escribir expresiones de PHP. Es decir, no se pueden usar sentencias terminadas en punto y coma. No puede declarar clases ni usar [estructuras de control |https://www.php.net/manual/en/language.control-structures.php] como `if`, `foreach`, `switch`, `return`, `try`, `throw` y otras, para las que Latte ofrece sus [etiquetas|tags]. Tampoco puede usar [atributos |https://www.php.net/manual/en/language.attributes.php], [comillas invertidas |https://www.php.net/manual/en/language.operators.execution.php] ni algunas [constantes mágicas |https://www.php.net/manual/en/language.constants.magic.php]. Tampoco puede usar `unset`, `echo`, `include`, `require`, `exit` ni `eval`, porque no son funciones, sino construcciones especiales del lenguaje PHP y, por tanto, no son expresiones. Solo se admiten los comentarios multilínea `/* ... */`.

Estas limitaciones se pueden sortear activando la extensión [RawPhpExtension |develop#RawPhpExtension], que permite usar cualquier código PHP dentro de la etiqueta `{php ...}`, bajo la responsabilidad del autor de la plantilla.

Sintaxis

La sintaxis de Latte nació de las necesidades prácticas de los diseñadores web. Buscábamos la sintaxis más amable posible, con la que se puedan escribir con elegancia construcciones que de otro modo son un auténtico reto. Al mismo tiempo, todas las expresiones se escriben exactamente igual que en PHP, así que no tiene que aprender un lenguaje nuevo. Simplemente aprovecha lo que ya sabe.

A continuación tiene una plantilla mínima que ilustra varios elementos básicos: etiquetas, n:atributos, comentarios y filtros.

{* esto es un comentario *}
<ul n:if=$items>                  {* n:if es un n:atributo *}
{foreach $items as $item}         {* etiqueta que representa un bucle foreach *}
	<li>{$item|capitalize}</li>   {* etiqueta que muestra una variable con un filtro *}
{/foreach}                        {* fin del bucle *}
</ul>

Veamos más de cerca estos elementos importantes y cómo pueden ayudarle a crear una plantilla estupenda.

Etiquetas

Una plantilla contiene etiquetas que controlan su lógica (por ejemplo, bucles foreach) o imprimen expresiones. Para ambas cosas se usa un único delimitador { ... }, así que, a diferencia de otros sistemas, no tiene que pensar qué delimitador usar en cada situación. Si al carácter { le sigue inmediatamente un espacio en blanco, unas comillas u otra { o }, Latte no lo considera el comienzo de una etiqueta, lo que le permite usar sin problemas construcciones de JavaScript, JSON o reglas CSS en sus plantillas.

Vea el resumen de todas las etiquetas. Además, puede crear sus propias etiquetas personalizadas. También puede cambiar los delimitadores { } o desactivarlos por completo (con {syntax double}, {syntax off} o el atributo n:syntax); vea cambiar la sintaxis.

Latte entiende PHP

Dentro de las etiquetas puede usar las expresiones de PHP que ya conoce:

Además, Latte enriquece la sintaxis de PHP con varias extensiones cómodas.

n:atributos

Toda etiqueta par, como {if} … {/if}, que opere sobre un único elemento HTML se puede reescribir en forma de n:atributo. Por ejemplo, el {foreach} del ejemplo introductorio también podría escribirse así:

<ul n:if=$items>
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>

La funcionalidad se aplica entonces al elemento HTML en el que está colocada:

{var $items = ['I', '♥', 'Latte']}

<p n:foreach="$items as $item">{$item}</p>

imprime:

<p>I</p>
<p>♥</p>
<p>Latte</p>

Con el prefijo inner- podemos modificar el comportamiento para que se aplique solo a la parte interior del elemento:

<div n:inner-foreach="$items as $item">
	<p>{$item}</p>
	<hr>
</div>

Imprime:

<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>

O bien, con el prefijo tag-, aplicamos la funcionalidad solo a las propias etiquetas HTML:

<p><a href={$url} n:tag-if="$url">Title</a></p>

Lo que imprime, según el valor de la variable $url:

{* cuando $url está vacía *}
<p>Title</p>

{* cuando $url contiene 'https://nette.org' *}
<p><a href="https://nette.org">Title</a></p>

Los n:atributos no son, sin embargo, solo un atajo para las etiquetas pares: existen también algunos n:atributos puros, por ejemplo el mejor amigo del programador n:class o el prácticamente indispensable n:href.

Además de la sintaxis con comillas <div n:if="$foo">, puede usar la sintaxis alternativa con llaves <div n:if={$foo}>. Su principal ventaja es que dentro de {...} puede usar libremente comillas simples y dobles:

<div n:if={str_contains($val, "foo")}> ... </div>

Atributos HTML inteligentes

Latte hace increíblemente fácil trabajar con los atributos HTML estándar. Gestiona por usted los atributos booleanos como checked, elimina los atributos que contienen null y le permite componer los valores de class y style con arrays. Incluso serializa automáticamente los datos de los atributos data- a JSON.

{* null elimina el atributo *}
<div title={$title}>

{* el booleano controla la presencia de los atributos booleanos *}
<input type="checkbox" checked={$isChecked}>

{* los arrays funcionan en class *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* los arrays se codifican en JSON en los atributos data- *}
<div data-config={[theme: dark, version: 2]}>

Más información en el capítulo aparte Atributos HTML inteligentes.

Filtros

Vea el resumen de los filtros estándar.

Los filtros se escriben tras el símbolo de tubería (se admite un espacio delante):

<h1>{$heading|upper}</h1>

Los filtros se pueden encadenar y se aplican en orden de izquierda a derecha:

<h1>{$heading|lower|capitalize}</h1>

Los argumentos van tras el nombre del filtro después de dos puntos, y los siguientes se separan con comas; también funciona la llamada entre paréntesis:

<h1>{$heading|truncate:20,''}</h1>
<h1>{$heading|truncate(20, '')}</h1>

Los filtros también se pueden aplicar a una expresión:

{var $name = ($title|upper) . ($subtitle|lower)}

A un bloque:

<h1>{block |lower}{$heading}{/block}</h1>

O directamente a un valor (en combinación con la etiqueta {=expr}):

<h1>{='  Hello world  '|trim}</h1>

Si el valor puede ser null y quiere evitar que se aplique el filtro en ese caso, use el filtro nullsafe ?|:

<h1>{$heading?|upper}</h1>

Etiquetas HTML dinámicas

Latte admite etiquetas HTML dinámicas, útiles cuando necesita flexibilidad en los nombres de las etiquetas:

<h{$level}>Heading</h{$level}>

Por ejemplo, el código anterior puede generar <h1>Heading</h1> o <h2>Heading</h2> según el valor de la variable $level. Las etiquetas HTML dinámicas en Latte deben ser siempre pares. Su alternativa es n:tag.

Como Latte es un sistema de plantillas seguro, comprueba que el nombre de etiqueta resultante sea válido y no contenga valores indeseados o maliciosos. También se asegura de que el nombre de la etiqueta de cierre coincida siempre con el de la de apertura.

Comentarios

Los comentarios se escriben así y no llegan a la salida:

{* esto es un comentario en Latte *}

Dentro de las etiquetas funcionan los comentarios de PHP:

{include 'file.info', /* value: 123 */}

Control del espacio en blanco

Latte trata el espacio en blanco de forma inteligente. Puede sangrar su código libremente para hacerlo legible y la salida sigue quedando limpia. Cuando una etiqueta de control aparece sola en una línea, se elimina de la salida toda la línea (la sangría y el salto de línea); esto no vale para las etiquetas que imprimen salida, como {$var}, {=...} o {_...}, que conservan su sangría y su salto de línea final:

<ul>
	{foreach $items as $item}
	<li>{$item}</li>
	{/foreach}
</ul>

Imprime:

<ul>
	<li>foo</li>
	<li>bar</li>
</ul>

¿Y si una etiqueta no está sola en la línea, sino junto a otro contenido? El espacio en blanco anterior a la etiqueta pertenece entonces al interior de la etiqueta:

<div>
	{if $foo}hello{/if}
</div>

La sangría está, de hecho, dentro del {if}: cuando $foo es falso, no se imprime nada, ni siquiera la sangría o una línea vacía. Cuando $foo es verdadero, la salida incluye naturalmente la sangría. Usted se limita a escribir plantillas bien estructuradas y la salida siempre queda limpia.

Para una salida aún más limpia puede activar la función Dedent, que elimina además la sangría provocada por el anidamiento dentro de etiquetas pares como {if} o {foreach}.

Azúcar sintáctico

Cadenas sin comillas

En las cadenas sencillas se pueden omitir las comillas:

as in PHP:   {var $arr = ['hello', 'btn--default', '€']}

abbreviated: {var $arr = [hello, btn--default, €]}

Son cadenas sencillas las compuestas únicamente por letras, dígitos, guiones bajos, guiones y puntos. No pueden empezar por un dígito ni empezar o terminar con un guion. No pueden estar formadas solo por letras mayúsculas y guiones bajos, porque entonces se consideran constantes (por ejemplo, PHP_VERSION). Y no pueden coincidir con las palabras clave: and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Constantes

Use el separador del espacio de nombres global para distinguir las constantes globales de las cadenas sencillas:

{if \PROJECT_ID === 1} ... {/if}

Esta notación es del todo válida en el propio PHP, donde la barra invertida indica que la constante está en el espacio de nombres global.

Operador ternario abreviado

Si el tercer valor del operador ternario está vacío, se puede omitir:

as in PHP:   {$stock ? 'In stock' : ''}

abbreviated: {$stock ? 'In stock'}

Notación moderna de claves en arrays

Las claves de los arrays se pueden escribir de forma parecida a los parámetros nombrados al llamar a funciones:

as in PHP:   {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

modern:      {var $arr = [one: 'item 1', two: 'item 2']}

Filtros

Los filtros se pueden usar sobre cualquier expresión; basta con encerrar toda la expresión entre paréntesis:

{var $content = ($text|truncate: 30|upper)}

Operador in

El operador in puede sustituir a la función in_array(). La comparación es siempre estricta:

{* como in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}

Una ventana a la historia

A lo largo de su historia, Latte introdujo varias formas de azúcar sintáctico que aparecieron en el propio PHP unos años más tarde. Por ejemplo, en Latte se podían escribir los arrays como [1, 2, 3] en lugar de array(1, 2, 3), o usar el operador nullsafe $obj?->foo, mucho antes de que fuera posible en el propio PHP. Latte introdujo también el operador de expansión de arrays (expand) $arr, equivalente al actual operador ...$arr de PHP.

Limitaciones de PHP en Latte

En Latte solo se pueden escribir expresiones de PHP. Es decir, no se pueden usar sentencias terminadas en punto y coma. No puede declarar clases ni usar estructuras de control como if, foreach, switch, return, try, throw y otras, para las que Latte ofrece sus etiquetas. Tampoco puede usar atributos, comillas invertidas ni algunas constantes mágicas. Tampoco puede usar unset, echo, include, require, exit ni eval, porque no son funciones, sino construcciones especiales del lenguaje PHP y, por tanto, no son expresiones. Solo se admiten los comentarios multilínea /* ... */.

Estas limitaciones se pueden sortear activando la extensión RawPhpExtension, que permite usar cualquier código PHP dentro de la etiqueta {php ...}, bajo la responsabilidad del autor de la plantilla.