Fundamentos de Twig

1. Introducción a Twig

Twig (http://twig.sensiolabs.org) es el nuevo motor de plantillas presentado a Drupal 8 y es un complemento de Symfony, el nuevo framework PHP en el que se basa Drupal 8. Twig nos proporciona una forma rápida y segura de separar contenido de la lógica PHP de una manera que hace que sea más fácil para los no desarrolladores trabajar con plantillas.

Para ayudarnos a tener una mejor idea de cómo trabajar con Twig, profundicemos en los pasos necesarios para habilitar la depuración de Twig.

2. Habilitando depuración Twig

Cuando la depuración de Twig está activada en Drupal, podemos rastrear qué se está utilizando en la plantilla, dónde se encuentra la plantilla y una lista de nombres de archivo sugeridos para anular una plantilla. Esta funcionalidad es muy ventajosa y, de hecho, es bastante sencilla de configurar siguiendo estos pasos:

  1. Abre el archivo development.services.yml ubicado en la carpeta /sites.

  2. Agrega las siguientes líneas al final del archivo:

parameters: twig.config: debug : true auto_reload: true cache: false
  1. Guarda el archivo.

  2. Borra la caché de Drupal.

Si navegamos de regreso a la página de inicio e inspeccionamos el marcado utilizando las herramientas de desarrollo de Google Chrome, ahora podemos ver la información de salida de depuración de Twig, como se muestra en la siguiente imagen:

Hay un par de cosas que debemos tener en cuenta cuando se habilita la depuración de Twig:

FILE NAME SUGGESTIONS: esto muestra sugerencias para nombrar plantillas de Twig HTML y las muestra en el orden de precedencia en el que Drupal buscaría plantillas.

OUTPUT: muestra la ubicación de la plantilla que se muestra actualmente, que en nuestro caso, es themes/twig/page.html.twig.

Recuerda que solo veremos la salida de depuración cuando tengamos habilitada la depuración de Twig como parte de nuestro entorno de desarrollo local. Lo mejor es recordar desactivar la depuración antes de mover un sitio de Drupal a producción. Entonces, ahora que tenemos una idea de lo que Twig debug proporciona, comencemos a escribir algunos de nuestra propia sintaxis de Twig, comenzando con los comentarios.

3. Fundamentos de Twig

Una plantilla de Twig genera PHP con una sintaxis orientada a la plantilla utilizando las llaves de apertura y cierre {{…}}. Esta sintaxis interpreta la variable entre corchetes y obtiene la salida HTML en su lugar.

Los siguientes son tres tipos de delimitadores en Twig que hacen que se lleve a cabo una evaluación:

  1. El primero es el comentario de Twig, que usa la etiqueta {# … #} para proporcionar comentarios en línea o alrededor de una sección de HTML.

  2. Luego está la etiqueta de impresión {{ … }} que se usa para imprimir el resultado de una expresión o variable. La etiqueta de impresión se puede usar sola o dentro de una sección de HTML.

  3. La tercera etiqueta es para ejecutar una declaración como lógica condicional, estructuras de bucle o la asignación de valores a variables y se expresa usando {% … %}.

Cada uno de los tres delimitadores se usará cuando hagamos cualquier tipo de proyectos de tematización dentro de Drupal 8. Descubriremos que son tan simples como usar cualquier elemento HTML común, y rápidamente escribiremos estas etiquetas.

3.1. Variables comentadas

Estamos familiarizados con los comentarios HTML, como <!-- Este es un comentario →, que nos permite agregar texto descriptivo a nuestro marcado. Vimos un ejemplo de esto en el resultado de depuración de Twig una vez que lo habilitamos. Twig nos brinda la posibilidad de agregar comentarios también con la sintaxis {# Este es un comentario #}.

Si abrimos page.html.twig con nuestro editor, podemos agregar un comentario de Twig así:

{# This is a comment in Twig #} <h1>Welcome to Twig!</h1>

Una vez guardada nuestra plantilla, actualiza el navegador e inspecciona el encabezado. Notaremos que en realidad no vemos el comentario que se muestra. A diferencia de los comentarios HTML, los comentarios Twig están ocultos a la salida del navegador y están destinados solo para el desarrollador.

3.2. Variables de configuración

Twig también puede asignar valores a variables usando una técnica llamada Asignación.

La asignación utiliza la etiqueta de conjunto para colocar un valor en una variable, que luego se puede utilizar dentro de una plantilla para generar el valor.

Abre page.html.twig y agrega lo siguiente sobre nuestro encabezado:

{# Setting a variable #} {% set name = 'Drupal' %} {# This is a comment in Twig #} <h1>Welcome to Twig!</h1>

Si guardamos nuestra plantilla y actualizamos el navegador, no veremos ningún cambio en nuestro HTML, ya que solo estamos configurando una variable pero no usándola en ningún lugar del documento.

Entonces, ¿cómo utilizamos una variable?

3.3. Imprimir variables

Twig nos permite imprimir variables simplemente haciendo referencia a ellas dentro de nuestro documento utilizando la sintaxis {{ variable }} para que el intérprete reemplace el nombre de la variable con el valor almacenado en él. Podemos probar esto reemplazando la palabra Twig en nuestro encabezado con la variable name.

Abre page.html.twig y agrega lo siguiente:

{# Setting a variable #} {% set name = 'Drupal' %} {# This is a comment in Twig #} <h1>Welcome to {{ name }}</h1>

Si guardamos nuestra plantilla y actualizamos el navegador, veremos que nuestro encabezado ahora dice Bienvenido a Drupal. La variable name que hemos establecido ha generado la palabra Drupal en su lugar. Esta es la misma técnica que utilizaremos para generar variables en nuestras plantillas Twig para mostrar el contenido de Drupal.

De hecho, si echamos un vistazo a nuestra plantilla html.html.twig, veremos una variedad de variables twig que se utilizan para generar contenido.

3.4. Variables de dumping

Mientras tematizamos en Drupal trabajaremos con variables simples y complejas que consisten en arrays de PHP que contienen múltiples valores.

Sabiendo que puede haber valores múltiples, a veces es útil volcar el contenido de la variable para saber exactamente con qué estamos trabajando. La función {{ dump() }} nos permite ver información sobre una variable de plantilla y solo está disponible cuando la depuración de Twig está activada.

Tomemos nuestra variable de nombre, por ejemplo, y volcamos el contenido para ver lo que contiene.

Abre page.html.twig y agrega lo siguiente a la parte inferior de la plantilla:

{# Dumping variables #} {{ dump(name) }}

Si guardamos nuestra plantilla y actualizamos el navegador, veremos que la variable name se descarga a la página que muestra información adicional sobre nuestra variable.

Usando la función dump() podemos introspectar más de una variable a la vez pasando múltiples argumentos. Probemos esto agregando una variable Drupal adicional llamada is_front, como se muestra en el siguiente código:

{# Dumping variables #} <pre>{{ dump(name, is_front) }}</pre>

Si guardamos nuestra plantilla y actualizamos el navegador veremos que la variable is_front se descarga a la página y también mostraremos más información, como se muestra en la siguiente imagen:

Por ahora, deberíamos sentirnos cómodos trabajando con una plantilla Twig y variables.

Sin embargo, podemos hacer mucho más con Twig que solo imprimir variables.

También podemos aplicar filtros a las variables para lograr diferentes funcionalidades.

4. Filtros

Los filtros nos proporcionan una forma de modificar variables. Los filtros generalmente están separados por un carácter de tubería (|) y pueden aceptar argumentos según el propósito del filtro.

Twig nos proporciona actualmente más de 30 filtros que podemos aplicar a las variables. Probemos los filtros ahora aplicando un filtro en mayúsculas en nuestra variable name.

Abre page.html.twig y agrega lo siguiente:

{# Apply filter to name variable #} <p>{{ name|upper }} Rocks.</p>

Si guardamos nuestra plantilla y actualizamos el navegador, ahora veremos que la variable de nombre se convierte en mayúscula dentro de nuestra etiqueta de párrafo, como se muestra en la siguiente imagen:

También podemos usar filtros para envolver secciones de HTML y variables, que aplican el filtro a más de un elemento a la vez. Un ejemplo de esto sería si quisiéramos en mayúsculas un párrafo entero en vez de solo la variable name.

Abre page.html.twig y agrega lo siguiente:

{% filter upper %} <p>{{ name }} is the best cms around.</p> {% endfilter %}

Si guardamos nuestra plantilla y actualizamos el navegador, veremos que todo el párrafo, incluida la variable name, se convierte a mayúsculas, como se muestra en la siguiente imagen:

Este es solo un ejemplo de uno de los muchos filtros que se pueden aplicar a variables dentro de Twig. Para obtener una lista detallada de filtros, podemos consultar http://twig.sensiolabs.org/doc/filters/index.html.

5. Estructuras de control

Habrá situaciones mientras te dedicas a Twig, donde tendremos que verificar si una variable es verdadera o falsa o si tenemos que recorrer una variable para generar múltiples valores contenidos en una matriz.

Las estructuras de control en Twig nos permiten contabilizar este tipo de funciones usando bloque {% … %} para probar expresiones y recorrer variables que contienen matrices.

Cada estructura de control contiene una etiqueta de apertura y cierre similar a la lógica de PHP.

Echemos un vistazo a algunas de las estructuras de control más utilizadas comenzando con la etiqueta if utilizada para probar una expresión.

Abre page.html.twig y agrega lo siguiente:

{# Conditional logic #}
{% set offline = false %}
{% if offline == true %}
<p>Website is in maintenance mode.</p>
{% endif %}
Si guardamos nuestra plantilla y actualizamos el navegador, no veremos nada que realmente se muestre todavía. La razón es que la variable offline está configurada actualmente como falsa y estamos verificando si es verdadera.

Abre page.html.twig y edita la variable offline cambiando su valor a verdadero:

{# Conditional logic #} {% set offline = true %} {% if offline == true %} <p>Website is in maintenance mode.</p>

Ahora vuelve a guardar la plantilla y mira la página en el navegador. Esta vez veremos nuestro párrafo mostrado, como se muestra en la siguiente imagen:

Por ahora, estamos empezando a ver cómo las estructuras de control dentro de Twig pueden ser útiles para ocultar o mostrar ciertos márgenes dentro de nuestra plantilla en función del valor de una variable. Esto será útil cuando tenemos ciertas regiones que queremos mostrar cuando un bloque se coloca en una región.

La otra estructura de control comúnmente utilizada en Twig es la de bucle. La etiqueta for se usa para recorrer cada elemento en una secuencia. Para nuestro ejemplo, probemos un bucle basado en una cantidad de elementos y generando el recuento.

Abre page.html.twig y agrega lo siguiente:

{# Looping #} {% for i in 0 ..10 %} {{ i }} {% endfor %}

Si guardamos nuestra plantilla y vemos la página en el navegador, se nos presentará el recuento dentro de nuestro bucle que se muestra en la página comenzando en 0 y llegando a 10, como se muestra en la imagen:

Esto es un bucle simple, y solo demuestra el uso de la etiqueta for. Una vez que comenzamos a crear plantillas Twig adicionales, podemos recorrer las variables más complejas de Drupal. Se puede encontrar documentación más extensa sobre la etiqueta for en http://twig.sensiolabs.org/doc/tags/for.html.

6. Variables de plantilla

Drupal 8 usa variables para generar datos dentro de las plantillas Twig. Sabemos que las variables generalmente consisten en cualquier cosa, desde una cadena simple hasta un objeto complejo que contiene una matriz de valores. Si miramos la plantilla html.html.twig, veremos documentación que describe las variables disponibles junto con el nombre de la variable y una descripción de lo que contiene la variable:

Variables: logged_in: A flag indicating if user is logged in. root_path: The root path of the current page (e.g., node, admin, user). node_type: The content type for the current node, if the page is a node. head_title: List of text elements that make up the head_title variable. May contain or more of the following: - title: The title of the page. - name: The name of the site. - slogan: The slogan of the site. - page_top: Initial rendered markup. This should be printed before 'page'. - page: The rendered page markup. - page_bottom: Closing rendered markup. This variable should be printed after 'page'. - db_offline: A flag indicating if the database is offline. - placeholder_token: The token for generating head, css, js and js-bottom placeholders.

Cada una de las variables a las que nuestra plantilla tiene acceso se puede generar usando la sintaxis de Twig. Por ejemplo, la variable head_title genera el título de nuestra página dentro del elemento <title>.

Drupal también usa {{ attributes }} para imprimir información adicional en nuestra página, por ejemplo, el elemento <body> para dar salida a las clases de CSS que necesitan los módulos o temas.

Cada plantilla con la que trabajaremos usa variables para generar el contenido de la base de datos. ¿Qué pasa si queremos agregar variables adicionales a Drupal? Aquí es donde el rol del archivo de tema entra en uso.

7. El papel del archivo de tema en Drupal

Los temas pueden ser simples de componer, a veces contienen un único archivo de configuración, un par de plantillas de Twig y algunos recursos. Sin embargo, habrá ocasiones en que necesitemos interceptar y anular variables y datos que Drupal genera antes de que lleguen a nuestras plantillas Twig. La API de Drupal (https://api.drupal.org/api/drupal/8) nos permite crear un archivo *.theme donde podemos agregar funciones de tema que pueden engancharse a la API usando diferentes tipos de llamadas a funciones.

  • Preprocess: este es un conjunto de llamadas a función específicas de diferentes plantillas que nos permiten manipular variables antes de que salgan a la página.

  • Hooks: este es un conjunto de llamadas a funciones para enganchar en la API de Drupal que nos permite alterar variables y anular las implementaciones predeterminadas.

8. Preprocesadores y ganchos

La función principal de las funciones del preprocesador es preparar las variables que se utilizarán en nuestras plantillas Twig utilizando las funciones template_preprocess. Estas funciones hacen referencia al tema y la plantilla que queremos interceptar. Escribiremos un ejemplo de interceptación de las variables de plantilla html.html.twig utilizadas en nuestro tema Twig de la siguiente manera:

twig_preprocess_html(&$variables) { }

Con esta simple llamada de función, podemos engancharnos al preproceso del tema para interceptar el argumento $variables y manipularlo según sea necesario antes de que nuestra plantilla reciba las variables. Para que podamos usar esta función, debemos hacer los siguientes pasos:

  1. Crea un archivo twig.theme dentro de la carpeta themes/twig. El archivo twig.theme contendrá todas las funciones PHP que escribiremos para trabajar con la API de Drupal.

  2. Agrega lo siguiente dentro del archivo twig.theme y luego guarda el archivo como:

<?php /** * Implements hook_preprocess_html(). */ function twig_preprocess_html(&$variables) { // add to classes $variables['attributes']['class'][] = 'twig'; }

Cada vez que agreguemos un archivo o plantilla por primera vez, necesitaremos borrar la caché de Drupal.

9. Anulación de variables

Ahora que hemos creado nuestro archivo twig.theme y tenemos el esquema de nuestro primer gancho de preproceso, echemos un vistazo a cómo anular una variable. Anteriormente, vimos que Drupal estaba agregando clases a nuestra etiqueta corporal usando la variable $attributes.

Pero, ¿y si queremos agregar clases adicionales específicas para nuestro tema?

Abre twig.theme y edita la función de preproceso para incluir lo siguiente:

/**
* Implements hook_preprocess_html().
*/
function twig_preprocess_html(&$variables) {
    // add to classes
    $variables['attributes']['class'][] = 'twig';
}

Ahora si guardamos nuestro archivo twig.theme y actualizamos el navegador, veremos que nuestra clase se agrega, como se muestra en la siguiente imagen:

Si bien solo hemos tocado la superficie de la funcionalidad que podemos usar al tematizar, deliberadamente no profundizaremos en todas las llamadas a API a las que tenemos acceso con Drupal 8. Si estás interesado en profundizar, puedes encontrar la referencia en https://api.drupal.org/api/drupal/8.

Una última cosa a tener en cuenta es que podemos hacer referencia a los archivos de ejercicios completados para el capítulo 3, si tenemos que comparar cualquiera de los trabajos que acabamos de completar o realizar una restauración de la base de datos.