Plantillas
Nette utiliza el sistema de plantillas Latte. Se utiliza Latte porque es el sistema de plantillas más seguro para PHP, y al mismo tiempo el sistema más intuitivo. Usted no tiene que aprender mucho nuevo, sólo necesita saber PHP y algunas etiquetas Latte.
Lo habitual es que la página se complete a partir de la plantilla layout + la plantilla action. Este es el aspecto que podría
tener una plantilla de maquetación, fíjate en los bloques {block}
y la etiqueta {include}
:
<!DOCTYPE html>
<html>
<head>
<title>{block title}My App{/block}</title>
</head>
<body>
<header>...</header>
{include content}
<footer>...</footer>
</body>
</html>
Y esta podría ser la plantilla de acción:
{block title}Homepage{/block}
{block content}
<h1>Homepage</h1>
...
{/block}
Define el bloque content
, que se inserta en lugar de {include content}
en el diseño, y también
redefine el bloque title
, que sobrescribe {block title}
en el diseño. Intenta imaginar el
resultado.
Búsqueda de plantillas
La ruta a las plantillas se deduce según una lógica simple. Se intenta ver si uno de estos archivos de plantilla existe en
relación con el directorio donde se encuentra la clase de presentador, donde <Presenter>
es el nombre del
presentador actual y <view>
es el nombre de la acción actual:
templates/<Presenter>/<view>.latte
templates/<Presenter>.<view>.latte
Si no se encuentra la plantilla, se intentará buscar en el directorio templates
un nivel más arriba, es decir,
al mismo nivel que el directorio con la clase presentadora.
Si la plantilla tampoco se encuentra allí, la respuesta es un error 404.
También puede cambiar la vista utilizando $this->setView('otherView')
. O, en lugar de buscar, especifique
directamente el nombre del archivo de plantilla utilizando
$this->template->setFile('/path/to/template.latte')
.
Puede cambiar las rutas donde se buscan las plantillas anulando el método formatTemplateFiles, que devuelve una matriz de posibles rutas de archivo.
El diseño se espera en los siguientes archivos:
templates/<Presenter>/@<layout>.latte
templates/<Presenter>.@<layout>.latte
templates/@<layout>.latte
diseño común a varios presentadores
<Presenter>
es el nombre del presentador actual y <layout>
es el nombre de la
maquetación, que por defecto es 'layout'
. El nombre puede cambiarse con
$this->setLayout('otherLayout')
, de modo que se intentarán los archivos @otherLayout.latte
.
También puede especificar directamente el nombre de archivo de la plantilla de maquetación con
$this->setLayout('/path/to/template.latte')
. El uso de $this->setLayout(false)
desactivará la
búsqueda de diseños.
Puede cambiar las rutas donde se buscan las plantillas anulando el método formatLayoutTemplateFiles, que devuelve una matriz de posibles rutas de archivo.
Variables en la plantilla
Las variables se pasan a la plantilla escribiéndolas en $this->template
y luego están disponibles en la
plantilla como variables locales:
$this->template->article = $this->articles->getById($id);
De esta forma podemos pasar fácilmente cualquier variable a las plantillas. Sin embargo, cuando desarrollamos aplicaciones robustas, a menudo es más útil limitarnos. Por ejemplo, definiendo explícitamente una lista de variables que la plantilla espera y sus tipos. Esto permitirá a PHP comprobar los tipos, al IDE autocompletar correctamente, y al análisis estático detectar errores.
¿Y cómo definimos tal enumeración? Simplemente en forma de una clase y sus propiedades. La nombramos de forma similar a
presenter, pero con Template
al final:
/**
* @property-read ArticleTemplate $template
*/
class ArticlePresenter extends Nette\Application\UI\Presenter
{
}
class ArticleTemplate extends Nette\Bridges\ApplicationLatte\Template
{
public Model\Article $article;
public Nette\Security\User $user;
// y otras variables
}
El objeto $this->template
en el presentador será ahora una instancia de la clase ArticleTemplate
.
Así que PHP comprobará los tipos declarados cuando se escriban. Y a partir de PHP 8.2 también advertirá sobre la escritura en
una variable no existente, en versiones anteriores se puede lograr lo mismo usando el rasgo Nette\SmartObject.
La anotación @property-read
es para IDE y análisis estático, hará que funcione el autocompletado, vea PhpStorm y el completado de código para
$this->template.

Puedes permitirte el lujo de susurrar en las plantillas también, simplemente instala el plugin Latte en PhpStorm y especifica el nombre de la clase al principio de la plantilla, ver el artículo „Latte: cómo escribir sistema:https://blog.nette.org/…ema-de-tipos“:
{templateType App\Presenters\ArticleTemplate}
...
Así es también como funcionan las plantillas en los componentes, sólo tienes que seguir la convención de nomenclatura y
crear una clase de plantilla FifteenTemplate
para el componente, por ejemplo FifteenControl
.
Si necesitas crear un $template
como una instancia de otra clase, utiliza el método
createTemplate()
:
public function renderDefault(): void
{
$template = $this->createTemplate(SpecialTemplate::class);
$template->foo = 123;
// ...
$this->sendTemplate($template);
}
Variables por defecto
Los presentadores y componentes pasan varias variables útiles a las plantillas de forma automática:
$basePath
es una ruta URL absoluta al directorio raíz (por ejemplo/CD-collection
)$baseUrl
es una URL absoluta al directorio raíz (por ejemplohttp://localhost/CD-collection
)$user
es un objeto que representa al usuario$presenter
es el presentador actual$control
es el componente o presentador actual$flashes
lista de mensajes enviados por el métodoflashMessage()
Si utilizas una clase de plantilla personalizada, estas variables se pasan si creas una propiedad para ellas.
Creación de enlaces
En la plantilla creamos enlaces a otros presentadores y acciones de la siguiente manera:
<a n:href="Product:show">detail</a>
Atributo n:href
es muy útil para etiquetas HTML <a>
. Si queremos imprimir el enlace en otro
lugar, por ejemplo en el texto, utilizamos {link}
:
URL is: {link Home:default}
Para más información, véase Creación de enlaces.
Filtros personalizados, etiquetas, etc.
El sistema de plantillas Latte puede ampliarse con filtros personalizados, funciones, etiquetas, etc. Esto puede hacerse
directamente en el método render<View>
o en el método beforeRender()
:
public function beforeRender(): void
{
// adding a filter
$this->template->addFilter('foo', /* ... */);
// or configure the Latte\Engine object directly
$latte = $this->template->getLatte();
$latte->addFilterLoader(/* ... */);
}
La versión 3 de Latte ofrece una forma más avanzada creando una extensión para cada proyecto web. He aquí un ejemplo aproximado de una clase de este tipo:
namespace App\Templating;
final class LatteExtension extends Latte\Extension
{
public function __construct(
private App\Model\Facade $facade,
private Nette\Security\User $user,
// ...
) {
}
public function getFilters(): array
{
return [
'timeAgoInWords' => $this->filterTimeAgoInWords(...),
'money' => $this->filterMoney(...),
// ...
];
}
public function getFunctions(): array
{
return [
'canEditArticle' =>
fn($article) => $this->facade->canEditArticle($article, $this->user->getId()),
// ...
];
}
// ...
}
La registramos usando configuration:
latte:
extensions:
- App\Templating\LatteExtension
Traducir
Si estás programando una aplicación multilingüe, es probable que necesites mostrar parte del texto de la plantilla en
diferentes idiomas. Para ello, Nette Framework define una interfaz de traducción Nette\Localization\Translator, que tiene un
único método translate()
. Éste acepta el mensaje $message
, que normalmente es una cadena, y cualquier
otro parámetro. La tarea consiste en devolver la cadena traducida. No existe una implementación por defecto en Nette, puede
elegir según sus necesidades entre varias soluciones ya preparadas que puede encontrar en Componette. Su documentación le indica cómo configurar el traductor.
Las plantillas se pueden configurar con un traductor, que nos
habrán pasado, utilizando el método setTranslator()
:
protected function beforeRender(): void
{
// ...
$this->template->setTranslator($translator);
}
Alternativamente, el traductor se puede establecer utilizando la configuración:
latte:
extensions:
- Latte\Essential\TranslatorExtension
El traductor puede utilizarse, por ejemplo, como un filtro |translate
, con parámetros adicionales pasados al
método translate()
(véase foo, bar
):
<a href="basket">{='Basket'|translate}</a>
<span>{$item|translate}</span>
<span>{$item|translate, foo, bar}</span>
O como una etiqueta de subrayado:
<a href="basket">{_'Basket'}</a>
<span>{_$item}</span>
<span>{_$item, foo, bar}</span>
Para la traducción de secciones de plantillas, existe una etiqueta emparejada {translate}
(desde Latte 2.11,
antes se utilizaba la etiqueta {_}
):
<a href="order">{translate}Order{/translate}</a>
<a href="order">{translate foo, bar}Order{/translate}</a>
Translator se llama por defecto en tiempo de ejecución al renderizar la plantilla. La versión 3 de Latte, sin embargo, puede traducir todo el texto estático durante la compilación de la plantilla. Esto ahorra rendimiento porque cada cadena se traduce sólo una vez y la traducción resultante se escribe en el formulario compilado. Esto crea múltiples versiones compiladas de la plantilla en el directorio caché, una para cada idioma. Para ello, sólo tiene que especificar el idioma como segundo parámetro:
protected function beforeRender(): void
{
// ...
$this->template->setTranslator($translator, $lang);
}
Por texto estático entendemos, por ejemplo, {_'hello'}
o {translate}hello{/translate}
. El texto no
estático, como {_$foo}
, seguirá compilándose sobre la marcha.