Twig para Diseñadores de Plantillas

Este documento describe la sintaxis y semántica del motor de plantillas y será más útil como referencia para aquellos que crean plantillas Twig.

Sinopsis

Una plantilla es un archivo de texto regular. Puede generar cualquier formato basado en texto (HTML, XML, CSV, LaTeX, etc.). No tiene una extensión específica, .html o .xml están bien.

Una plantilla contiene variables o expresiones, que se reemplazan con valores cuando se evalúa la plantilla, y etiquetas, que controlan la lógica de la plantilla.

A continuación se muestra una plantilla mínima que ilustra algunos conceptos básicos. Cubriremos más detalles más adelante:

<!DOCTYPE html>
<html>
    <head>
        <title>Mi Página Web</title>
    </head>
    <body>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}
        </ul>

        <h1>Mi Página Web</h1>
        {{ a_variable }}
    </body>
</html>

Hay dos tipos de delimitadores: {% ... %} y {{ ... }}. El primero se utiliza para ejecutar sentencias como bucles for, el segundo muestra el resultado de una expresión.

Tip

Para experimentar con Twig, puedes usar el Twig Playground.

Integraciones de Terceros

Muchos IDEs soportan resaltado de sintaxis y autocompletado para Twig:

También te puede interesar:

  • Twig CS Fixer: una herramienta para verificar/corregir el estilo de código de tus plantillas
  • Twig Language Server: proporciona algunas características de lenguaje como resaltado de sintaxis, diagnósticos, autocompletado, ...
  • TwigQI: una extensión que analiza tus plantillas en busca de errores comunes durante la compilación
  • TwigStan: un analizador estático para plantillas Twig impulsado por PHPStan

Variables

Las plantillas Twig tienen acceso a variables proporcionadas por la aplicación PHP y variables creadas en plantillas mediante la etiqueta set. Estas variables pueden ser manipuladas y mostradas en la plantilla.

Twig intenta abstraer los tipos PHP tanto como sea posible y funciona con algunos tipos básicos, soportados por filtros, funciones y tests entre otros:

Tipo Twig Tipo PHP
string Un string o un objeto Stringable
number Un entero o un float
boolean true o false
null null
iterable (mapeo) Un array
iterable (secuencia) Un array
iterable (objeto) Un objeto iterable
object Un objeto

Los tipos iterable y object exponen atributos a los que puedes acceder mediante el operador punto (.):

{{ user.name }}

Note

Es importante saber que las llaves no son parte de la variable sino de la sentencia de impresión. Cuando accedes a variables dentro de etiquetas, no pongas las llaves alrededor de ellas.

Si una variable o atributo no existe, el comportamiento depende del valor de la opción strict_variables (ver opciones de entorno):

  • Cuando es false, devuelve null;
  • Cuando es true, lanza una excepción.

Aprende más sobre el operador punto.

Variables Globales

Las siguientes variables siempre están disponibles en las plantillas:

  • _self: referencia el nombre de la plantilla actual;
  • _context: referencia el contexto actual;
  • _charset: referencia el charset actual.

Estableciendo Variables

Puedes asignar valores a variables dentro de bloques de código. Las asignaciones usan la etiqueta set:

{% set name = 'Fabien' %}
{% set numbers = [1, 2] %}
{% set map = {'city': 'Paris'} %}

Filtros

Las variables y expresiones pueden ser modificadas por filtros. Los filtros se separan de la variable por un símbolo de tubería (|). Múltiples filtros pueden encadenarse. La salida de un filtro se aplica al siguiente.

El siguiente ejemplo elimina todas las etiquetas HTML del name y lo convierte a título:

{{ name|striptags|title }}

Los filtros que aceptan argumentos tienen paréntesis alrededor de los argumentos. Este ejemplo une los elementos de una lista por comas:

{{ list|join(', ') }}

Para aplicar un filtro a una sección de código, envuélvela con la etiqueta apply:

{% apply upper %}
    Este texto se convierte a mayúsculas
{% endapply %}

Ve a la página filtros para aprender más sobre los filtros incorporados.

Warning

Como el operador filter tiene la mayor precedencia, usa paréntesis cuando filtres expresiones más "complejas":

{{ (1..5)|join(', ') }}

{{ ('HELLO' ~ 'FABIEN')|lower }}

Funciones

Las funciones pueden ser llamadas para generar contenido. Las funciones se llaman por su nombre seguido de paréntesis (()) y pueden tener argumentos.

Por ejemplo, la función range devuelve una lista que contiene una progresión aritmética de enteros:

{% for i in range(0, 3) %}
    {{ i }},
{% endfor %}

Ve a la página funciones para aprender más sobre las funciones incorporadas.

Argumentos con Nombre

Los argumentos con nombre son soportados en todas partes donde puedes pasar argumentos: funciones, filtros, tests, macros y argumentos del operador punto.

Note

Los argumentos con nombre para macros y argumentos del operador punto fueron añadidos en Twig 3.15.

Note

Twig soporta tanto = como : como separadores entre nombres de argumentos y valores, pero el soporte para : fue introducido en Twig 3.12.

{% for i in range(low: 1, high: 10, step: 2) %}
    {{ i }},
{% endfor %}

Usar argumentos con nombre hace que tus plantillas sean más explícitas sobre el significado de los valores que pasas como argumentos:

{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}

{# versus #}

{{ data|convert_encoding(from: 'iso-2022-jp', to: 'UTF-8') }}

Los argumentos con nombre también te permiten omitir algunos argumentos para los cuales no quieres cambiar el valor por defecto:

{# el primer argumento es el formato de fecha, que por defecto es el formato de fecha global si se pasa null #}
{{ "now"|date(null, "Europe/Paris") }}

{# o omite el valor del formato usando un argumento con nombre para la zona horaria #}
{{ "now"|date(timezone: "Europe/Paris") }}

También puedes usar tanto argumentos posicionales como con nombre en una llamada, en cuyo caso los argumentos posicionales deben siempre venir antes de los argumentos con nombre:

{{ "now"|date('d/m/Y H:i', timezone: "Europe/Paris") }}

Tip

Cada página de documentación de función, filtro y test tiene una sección donde se listan los nombres de todos los argumentos soportados.

Estructuras de Control

Una estructura de control se refiere a todas aquellas cosas que controlan el flujo de un programa - condicionales (es decir, if/elseif/else), bucles for, así como cosas como bloques. Las estructuras de control aparecen dentro de bloques {% ... %}.

Por ejemplo, para mostrar una lista de usuarios proporcionada en una variable llamada users, usa la etiqueta for:

<h1>Miembros</h1>
<ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
</ul>

La etiqueta if puede usarse para probar una expresión:

{% if users|length > 0 %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}

Ve a la página etiquetas para aprender más sobre las etiquetas incorporadas.

Comentarios

Para comentar parte de una plantilla, usa la sintaxis de comentario {# ... #}. Esto es útil para depurar o añadir información para otros diseñadores de plantillas o para ti mismo:

{# nota: plantilla deshabilitada porque ya no usamos esto
    {% for user in users %}
        ...
    {% endfor %}
#}

Note

Los comentarios en línea fueron añadidos en Twig 3.15.

Si quieres añadir comentarios dentro de un bloque, variable o comentario, usa un comentario en línea. Empiezan con # y continúan hasta el final de la línea:

{{
    # esto es un comentario en línea
    "Hello World"|upper
    # esto es un comentario en línea
}}

{{
    {
        # esto es un comentario en línea
        fruit: 'apple', # esto es un comentario en línea
        color: 'red', # esto es un comentario en línea
    }|join(', ')
}}

Los comentarios en línea también pueden estar en la misma línea que la expresión:

{{
    "Hello World"|upper # esto es un comentario en línea
}}

Como los comentarios en línea continúan hasta el final de la línea actual, el siguiente código no funciona ya que }} sería parte del comentario:

{{ "Hello World"|upper # this is an inline comment }}

Incluyendo Otras Plantillas

La función include es útil para incluir una plantilla y devolver el contenido renderizado de esa plantilla en la actual:

{{ include('sidebar.html.twig') }}

Por defecto, las plantillas incluidas tienen acceso al mismo contexto que la plantilla que las incluye. Esto significa que cualquier variable definida en la plantilla principal estará disponible también en la plantilla incluida:

{% for box in boxes %}
    {{ include('render_box.html.twig') }}
{% endfor %}

La plantilla incluida render_box.html.twig es capaz de acceder a la variable box.

El nombre de la plantilla depende del cargador de plantillas. Por ejemplo, el \Twig\Loader\FilesystemLoader te permite acceder a otras plantillas dando el nombre de archivo. Puedes acceder a plantillas en subdirectorios con una barra:

{{ include('sections/articles/sidebar.html.twig') }}

Este comportamiento depende de la aplicación que integra Twig.

Herencia de Plantillas

La parte más poderosa de Twig es la herencia de plantillas. La herencia de plantillas te permite construir una plantilla "esqueleto" base que contiene todos los elementos comunes de tu sitio y define bloques que las plantillas hijas pueden sobrescribir.

Es más fácil entender el concepto comenzando con un ejemplo.

Vamos a definir una plantilla base, base.html.twig, que define un documento esqueleto HTML que podría usarse para una página de dos columnas:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css"/>
            <title>{% block title %}{% endblock %} - Mi Página Web</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 por <a href="https://example.com/">ti</a>.
            {% endblock %}
        </div>
    </body>
</html>

En este ejemplo, las etiquetas block definen cuatro bloques que las plantillas hijas pueden rellenar. Todo lo que la etiqueta block hace es decirle al motor de plantillas que una plantilla hija puede sobrescribir esas porciones de la plantilla.

Una plantilla hija podría verse así:

{% extends "base.html.twig" %}

{% block title %}Índice{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Índice</h1>
    <p class="important">
        Bienvenido a mi impresionante página de inicio.
    </p>
{% endblock %}

La etiqueta extends es la clave aquí. Le dice al motor de plantillas que esta plantilla "extiende" otra plantilla. Cuando el sistema de plantillas evalúa esta plantilla, primero localiza el padre. La etiqueta extends debería ser la primera etiqueta en la plantilla.

Nota que como la plantilla hija no define el bloque footer, se usa en su lugar el valor de la plantilla padre.

Es posible renderizar los contenidos del bloque padre usando la función parent. Esto devuelve los resultados del bloque padre:

{% block sidebar %}
    <h3>Tabla de Contenidos</h3>
    ...
    {{ parent() }}
{% endblock %}

Tip

La página de documentación para la etiqueta extends describe características más avanzadas como anidamiento de bloques, ámbito, herencia dinámica y herencia condicional.

Note

Twig también soporta herencia múltiple vía "reutilización horizontal" con la ayuda de la etiqueta use.

Escape HTML

Al generar HTML desde plantillas, siempre existe el riesgo de que una variable incluya caracteres que afecten el HTML resultante. Hay dos enfoques: escapar manualmente cada variable o escapar automáticamente todo por defecto.

Twig soporta ambos, el escape automático está habilitado por defecto.

La estrategia de escape automático puede configurarse mediante la opción autoescape y por defecto es html.

Trabajando con Escape Manual

Si el escape manual está habilitado, es tu responsabilidad escapar las variables si es necesario. ¿Qué escapar? Cualquier variable que provenga de una fuente no confiable.

El escape funciona usando el filtro escape o e:

{{ user.username|e }}

Por defecto, el filtro escape usa la estrategia html, pero dependiendo del contexto de escape, podrías querer usar explícitamente otra estrategia:

{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}

Trabajando con Escape Automático

Ya sea que el escape automático esté habilitado o no, puedes marcar una sección de una plantilla para ser escapada o no usando la etiqueta autoescape:

{% autoescape %}
    Todo será escapado automáticamente en este bloque (usando la estrategia HTML)
{% endautoescape %}

Por defecto, el auto-escape usa la estrategia de escape html. Si muestras variables en otros contextos, necesitas escaparlas explícitamente con la estrategia de escape apropiada:

{% autoescape 'js' %}
    Todo será escapado automáticamente en este bloque (usando la estrategia JS)
{% endautoescape %}

Escapado

A veces es deseable o incluso necesario tener Twig ignorando partes que de otra manera manejaría como variables o bloques. Por ejemplo, si se usa la sintaxis por defecto y quieres usar {{ como string crudo en la plantilla y no comenzar una variable, tienes que usar un truco.

La forma más fácil es mostrar el delimitador de variable ({{) usando una expresión de variable:

{{ '{{' }}

Para secciones más grandes tiene sentido marcar un bloque como verbatim.

Macros

Las macros son comparables con funciones en lenguajes de programación regulares. Son útiles para reutilizar fragmentos HTML y no repetirse. Se describen en la documentación de la etiqueta macro.

Expresiones

Twig permite expresiones en todas partes.

Literales

La forma más simple de expresiones son los literales. Los literales son representaciones para tipos PHP como strings, números y arrays. Los siguientes literales existen:

  • "Hello World": Todo entre dos comillas dobles o simples es un string. Son útiles siempre que necesites un string en la plantilla (por ejemplo como argumentos para llamadas a funciones, filtros o solo para extender o incluir una plantilla).

    Nota que ciertos caracteres requieren escape:

    • \f: Avance de página
    • \n: Nueva línea
    • \r: Retorno de carro
    • \t: Tabulador horizontal
    • \v: Tabulador vertical
    • \x: Secuencia de escape hexadecimal
    • \0 a \377: Secuencias de escape octales que representan caracteres
    • \: Barra invertida

    Cuando se usan strings entre comillas simples, el carácter de comilla simple (') necesita ser escapado con una barra invertida (\'). Cuando se usan strings entre comillas dobles, el carácter de comilla doble (") necesita ser escapado con una barra invertida (\").

    Por ejemplo, un string entre comillas simples puede contener un delimitador si es precedido por una barra invertida (\) -- como en 'It\'s good'. Si el string contiene una barra invertida (ej. 'c:\Program Files') escápala duplicándola (ej. 'c:\\Program Files').

  • 42 / 42.23: Los enteros y números de punto flotante se crean escribiendo el número. Si hay un punto presente el número es un float, de lo contrario un entero. Los guiones bajos pueden usarse como separadores de dígitos para mejorar la legibilidad (-3_141.592_65 es equivalente a -3141.59265).

  • ["first_name", "last_name"]: Las secuencias se definen por una secuencia de expresiones separadas por una coma (,) y envueltas con corchetes ([]).

  • {"name": "Fabien"}: Los mapeos se definen por una lista de claves y valores separados por una coma (,) y envueltos con llaves ({}):

    {# claves como string #}
    {'name': 'Fabien', 'city': 'Paris'}
    
    {# claves como nombres (equivalente al mapeo anterior) #}
    {name: 'Fabien', city: 'Paris'}
    
    {# claves como integer #}
    {2: 'Twig', 4: 'Symfony'}
    
    {# las claves pueden omitirse si es lo mismo que el nombre de la variable #}
    {Paris}
    {# es equivalente a lo siguiente #}
    {'Paris': Paris}
    
    {# claves como expresiones (la expresión debe encerrarse entre paréntesis) #}
    {% set key = 'name' %}
    {(key): 'Fabien', (1 + 1): 2, ('ci' ~ 'ty'): 'city'}
  • true / false: true representa el valor verdadero, false representa el valor falso.

  • null: null representa ningún valor específico. Este es el valor devuelto cuando una variable no existe. none es un alias para null.

Las secuencias y mapeos pueden anidarse:

{% set complex = [1, {"name": "Fabien"}] %}

Tip

Usar strings entre comillas dobles o simples no tiene impacto en el rendimiento pero la interpolación de strings solo se soporta en strings entre comillas dobles.

Interpolación de Strings

La interpolación de strings (#{expression}) permite que cualquier expresión válida aparezca dentro de un string entre comillas dobles. El resultado de evaluar esa expresión se inserta en el string:

{{ "first #{middle} last" }}
{{ "first #{1 + 2} last" }}

Tip

Las interpolaciones de strings pueden ignorarse escapándolas con una barra invertida (\):

{# muestra first #{1 + 2} last #}
{{ "first \#{1 + 2} last" }}

Matemáticas

Twig te permite hacer matemáticas en plantillas; se soportan los siguientes operadores:

  • +: Suma dos números (los operandos se convierten a números). {{ 1 + 1 }} es 2.

  • -: Resta el segundo número del primero. {{ 3 - 2 }} es 1.

  • /: Divide dos números. El valor devuelto será un número de punto flotante. {{ 1 / 2 }} es {{ 0.5 }}.

  • %: Calcula el resto de una división entera. {{ 11 % 7 }} es 4.

  • //: Divide dos números y devuelve el resultado entero redondeado hacia abajo. {{ 20 // 7 }} es 2, {{ -20 // 7 }} es -3 (esto es solo azúcar sintáctico para el filtro round).

  • *: Multiplica el operando izquierdo con el derecho. {{ 2 * 2 }} devolvería 4.

  • **: Eleva el operando izquierdo a la potencia del operando derecho. {{ 2 ** 3 }} devolvería 8. Ten cuidado ya que el operador ** es asociativo por la derecha, lo que significa que {{ -1**0 }} es equivalente a {{ -(1**0) }} y no {{ (-1)**0 }}.

Lógica

Puedes combinar múltiples expresiones con los siguientes operadores:

  • and: Devuelve true si tanto el operando izquierdo como el derecho son true.
  • xor: Devuelve true si cualquiera el operando izquierdo o el derecho es true, pero no ambos.
  • or: Devuelve true si el operando izquierdo o el derecho es true.
  • not: Niega una sentencia.
  • (expr): Agrupa una expresión.

Note

Twig también soporta operadores a nivel de bit (b-and, b-xor, y b-or).

Note

Los operadores son sensibles a mayúsculas y minúsculas.

Comparaciones

Los siguientes operadores de comparación matemática son soportados en cualquier expresión: ==, !=, <, >, >=, y <=.

Operador Nave Espacial

El operador nave espacial (<=>) se usa para comparar dos expresiones. Devuelve -1, 0 o 1 cuando el primer operando es respectivamente menor que, igual a, o mayor que el segundo operando.

Note

Operadores Iterables

Comprueba que un iterable has every o has some de sus elementos devuelvan true usando una función flecha. La función flecha recibe el valor del iterable como su argumento:

{% set sizes = [34, 36, 38, 40, 42] %}

{% set hasOnlyOver38 = sizes has every v => v > 38 %}
{# hasOnlyOver38 es false #}

{% set hasOver38 = sizes has some v => v > 38 %}
{# hasOver38 es true #}

Para un iterable vacío, has every devuelve true y has some devuelve false.

Operadores de Contención

El operador in realiza una prueba de contención. Devuelve true si el operando izquierdo está contenido en el derecho:

{# devuelve true #}

{{ 1 in [1, 2, 3] }}

{{ 'cd' in 'abcde' }}

Tip

Puedes usar este operador para realizar una prueba de contención en strings, secuencias, mapeos u objetos que implementen la interfaz Traversable.

Para realizar una prueba negativa, usa el operador not in:

{% if 1 not in [1, 2, 3] %}

{# es equivalente a #}
{% if not (1 in [1, 2, 3]) %}

Los operadores starts with y ends with se usan para comprobar si un string comienza o termina con una subcadena dada:

{% if 'Fabien' starts with 'F' %}
{% endif %}

{% if 'Fabien' ends with 'n' %}
{% endif %}

Note

Para comparaciones de strings complejas, el operador matches te permite usar expresiones regulares:

{% if phone matches '/^[\\d\\.]+$/' %}
{% endif %}

Operador Test

El operador is realiza tests. Los tests pueden usarse para probar una variable contra una expresión común. El operando derecho es el nombre del test:

{# averigua si una variable es impar #}

{{ name is odd }}

Los tests pueden aceptar argumentos también:

{% if post.status is constant('Post::PUBLISHED') %}

Los tests pueden negarse usando el operador is not:

{% if post.status is not constant('Post::PUBLISHED') %}

{# es equivalente a #}
{% if not (post.status is constant('Post::PUBLISHED')) %}

Ve a la página tests para aprender más sobre los tests incorporados.

Otros Operadores

Los siguientes operadores no encajan en ninguna de las otras categorías:

  • |: Aplica un filtro.

  • ..: Crea una secuencia basada en el operando antes y después del operador (esto es azúcar sintáctico para la función range):

    {% for i in 1..5 %}{{ i }}{% endfor %}
    
    {# es equivalente a #}
    {% for i in range(1, 5) %}{{ i }}{% endfor %}

    Nota que debes usar paréntesis cuando lo combines con el operador de filtro debido a las reglas de precedencia de operadores:

    {{ (1..5)|join(', ') }}
  • ~: Convierte todos los operandos en strings y los concatena. {{ "Hola " ~ name ~ "!" }} devolvería (asumiendo que name es 'John') Hola John!.

  • ., []: Obtiene un atributo de una variable.

    El operador (.) abstrae la obtención de un atributo de una variable (métodos, propiedades o constantes de un objeto PHP, o elementos de un array PHP):

    {{ user.name }}

    Después del ., puedes usar cualquier expresión envolviéndola con paréntesis ().

    Un caso de uso es cuando el atributo contiene caracteres especiales (como - que sería interpretado como el operador menos):

    {# equivalente al no funcionamiento user.first-name #}
    {{ user.('first-name') }}

    Otro caso de uso es cuando el atributo es "dinámico" (definido mediante una variable):

    {{ user.(name) }}
    {{ user.('get' ~ name) }}

    Antes de Twig 3.15, usa la función attribute en su lugar para los dos casos de uso anteriores.

    Twig soporta una sintaxis específica mediante el operador [] para acceder a elementos en secuencias y mapeos:

    {{ user['name'] }}

    Al llamar a un método, puedes pasar argumentos usando el operador ():

    {{ html.generate_input() }}
    {{ html.generate_input('pwd', 'password') }}
    {# o usando argumentos con nombre #}
    {{ html.generate_input(name: 'pwd', type: 'password') }}
  • ?:: El operador ternario:

    {{ result ? 'sí' : 'no' }}
    {{ result ?: 'no' }} es lo mismo que {{ result ? result : 'no' }}
    {{ result ? 'sí' }} es lo mismo que {{ result ? 'sí' : '' }}
  • ??: El operador de fusión de null:

    {# devuelve el valor de result si está definido y no es null, 'no' en caso contrario #}
    {{ result ?? 'no' }}
  • ...: El operador de expansión puede usarse para expandir secuencias o mapeos o para expandir los argumentos de una llamada a función:

    {% set numbers = [1, 2, ...moreNumbers] %}
    {% set ratings = {'q1': 10, 'q2': 5, ...moreRatings} %}
    
    {{ 'Hello %s %s!'|format(...['Fabien', 'Potencier']) }}

    Note

    El soporte para expandir los argumentos de una llamada a función fue introducido en Twig 3.15.

  • =>: El operador flecha permite la creación de funciones. Una función está hecha de argumentos (usa paréntesis para múltiples argumentos) y una flecha (=>) seguida de una expresión a ejecutar. La expresión tiene acceso a todos los argumentos pasados. Las funciones flecha son soportadas como argumentos para filtros, funciones, tests, macros y llamadas a métodos.

    Por ejemplo, los filtros incorporados map, reduce, sort, filter, y find aceptan funciones flecha como argumentos:

    {{ people|map(p => p.first_name)|join(', ') }}

    Las funciones flecha pueden almacenarse en variables:

    {% set first_name_fn = (p) => p.first_name %}
    
    {{ people|map(first_name_fn)|join(', ') }}

    Note

    El soporte de funciones flecha para funciones, macros y llamadas a métodos fue añadido en Twig 3.15 (filtros y tests ya estaban soportados).

    Las funciones flecha pueden llamarse usando el filtro invoke.

    Note

    El filtro invoke fue añadido en Twig 3.19.

Operadores

Twig usa operadores para realizar varias operaciones dentro de plantillas. Entender la precedencia de estos operadores es crucial para escribir plantillas Twig correctas y eficientes.

Las reglas de precedencia de operadores son las siguientes, con los operadores de menor precedencia listados primero.

Precedencia Operador Tipo Asociatividad Descripción
512 ... prefix n/a Operador de expansión
300 \| infix Izquierda Llamada a filtro Twig
( Llamada a función Twig
. Obtener un atributo en una variable
[ Acceso a array
500 - prefix n/a
+
300 => 5 ?? infix Derecha Operador de fusión de null (a ?? b)
250 => infix Izquierda Función flecha (x => expr)
200 ** infix Derecha Operador de exponenciación
100 is infix Izquierda Tests Twig
is not Tests Twig
60 * infix Izquierda
/
// División de piso
%
50 => 70 not prefix n/a
40 => 27 ~ infix Izquierda
30 + infix Izquierda
-
25 .. infix Izquierda
20 == infix Izquierda
!=
<=>
<
>
>=
<=
not in
in
matches
starts with
ends with
has some
has every
18 b-and infix Izquierda
17 b-xor infix Izquierda
16 b-or infix Izquierda
15 and infix Izquierda
12 xor infix Izquierda
10 or infix Izquierda
5 ?: infix Derecha Operador Elvis (a ?: b)
?: Operador Elvis (a ?: b)
0 ( prefix n/a Expresión de grupo explícita (a)
literal Un valor literal (boolean, string, number, sequence, mapping, ...)
? infix Izquierda Operador condicional (a ? b : c)

Aquí está la misma tabla para Twig 4.0 con precedencias ajustadas:

Precedencia Operador Tipo Asociatividad Descripción
512 ... prefix n/a Operador de expansión
( infix Izquierda Llamada a función Twig
. Obtener un atributo en una variable
[ Acceso a array
500 - prefix n/a
+
300 \| infix Izquierda Llamada a filtro Twig
250 => infix Izquierda Función flecha (x => expr)
200 ** infix Derecha Operador de exponenciación
100 is infix Izquierda Tests Twig
is not Tests Twig
70 not prefix n/a
60 * infix Izquierda
/
// División de piso
%
30 + infix Izquierda
-
27 ~ infix Izquierda
25 .. infix Izquierda
20 == infix Izquierda
!=
<=>
<
>
>=
<=
not in
in
matches
starts with
ends with
has some
has every
18 b-and infix Izquierda
17 b-xor infix Izquierda
16 b-or infix Izquierda
15 and infix Izquierda
12 xor infix Izquierda
10 or infix Izquierda
5 ?? infix Derecha Operador de fusión de null (a ?? b)
?: Operador Elvis (a ?: b)
?: Operador Elvis (a ?: b)
0 ( prefix n/a Expresión de grupo explícita (a)
literal Un valor literal (boolean, string, number, sequence, mapping, ...)
? infix Izquierda Operador condicional (a ? b : c)

Sin usar ningún paréntesis, las reglas de precedencia de operadores se usan para determinar cómo convertir el código a PHP:

{{ 6 b-and 2 or 6 b-and 16 }}

{# se convierte al siguiente código PHP: (6 & 2) || (6 & 16) #}

Cambia la precedencia por defecto agrupando explícitamente expresiones con paréntesis:

{% set greeting = 'Hola ' %}
{% set name = 'Fabien' %}

{{ greeting ~ name|lower }}   {# Hola fabien #}

{# usa paréntesis para cambiar la precedencia #}
{{ (greeting ~ name)|lower }} {# hola fabien #}

Control de Espacios en Blanco

La primera nueva línea después de una etiqueta de plantilla se elimina automáticamente (como en PHP). Los espacios en blanco no son modificados más por el motor de plantillas, por lo que cada espacio en blanco (espacios, tabulaciones, nuevas líneas, etc.) se devuelve sin cambios.

También puedes controlar los espacios en blanco a nivel de etiqueta. Usando los modificadores de control de espacios en blanco en tus etiquetas, puedes recortar los espacios en blanco iniciales y/o finales.

Twig soporta dos modificadores:

  • Recorte de espacios en blanco mediante el modificador -: Elimina todos los espacios en blanco (incluyendo nuevas líneas);
  • Recorte de espacios en blanco de línea mediante el modificador ~: Elimina todos los espacios en blanco (excluyendo nuevas líneas). Usar este modificador a la derecha deshabilita la eliminación por defecto de la primera nueva línea heredada de PHP.

Los modificadores pueden usarse en cualquier lado de las etiquetas como en {%- o -%} y consumen todos los espacios en blanco para ese lado de la etiqueta. Es posible usar los modificadores en un lado de una etiqueta o en ambos lados:

{% set value = 'sin espacios' %}
{#- Sin espacios en blanco iniciales/finales -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}
{# muestra 'sin espacios' #}

<li>
    {{ value }}    </li>
{# outputs '<li>\n    sin espacios    </li>' #}

<li>
    {{- value }}    </li>
{# outputs '<li>sin espacios    </li>' #}

<li>
    {{~ value }}    </li>
{# outputs '<li>\nsin espacios    </li>' #}

Extensiones

Twig puede extenderse. Si quieres crear tus propias extensiones, lee el capítulo Creando una Extensión.