Sie sind auf Seite 1von 61

Manual de Twig

Release 1.2.0

Traducido por Nacho Pacheco

August 29, 2011

ndice general

1. Introduccin 1.1. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2. Instalando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3. Uso bsico de la API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Twig para diseadores de plantillas 2.1. Sinopsis . . . . . . . . . . . . . . . . . . 2.2. Integrando con IDEs . . . . . . . . . . . 2.3. Variables . . . . . . . . . . . . . . . . . 2.4. Filtros . . . . . . . . . . . . . . . . . . . 2.5. Comentarios . . . . . . . . . . . . . . . 2.6. Control del espacio en blanco . . . . . . 2.7. Escapando . . . . . . . . . . . . . . . . 2.8. Herencia en plantillas . . . . . . . . . . 2.9. Importando comportamiento del contexto 2.10. Escapando HTML . . . . . . . . . . . . 2.11. Lista de las estructuras de control . . . . 2.12. Expresiones . . . . . . . . . . . . . . . . 2.13. Lista de ltros integrados . . . . . . . . 2.14. Lista de pruebas incorporadas . . . . . . 2.15. Lista de funciones globales . . . . . . . 2.16. Extendiendo . . . . . . . . . . . . . . . 2.17. Reutilizacin horizontal . . . . . . . . . 3. Twig para desarrolladores 3.1. Fundamentos . . . . . . . 3.2. Opciones del entorno . . . 3.3. Cargadores . . . . . . . . 3.4. Usando extensiones . . . 3.5. Extensiones incorporadas 3.6. Excepciones . . . . . . .

1 1 1 2 3 3 4 4 5 5 5 6 6 9 9 10 17 19 22 23 25 25 27 27 28 28 30 30 34 35 36

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

4. Extendiendo Twig 4.1. Globales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4.2. 4.3. 4.4.

Filtros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Etiquetas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

36 38 39 43 45 45 47 47 47 49 49 49 50 51 53 53 53 53 54 55 55 56 57

5. Creando una extensin Twig 5.1. Globales y funciones . . 5.2. Filtros . . . . . . . . . . 5.3. Etiquetas . . . . . . . . 5.4. Operadores . . . . . . . 5.5. Pruebas . . . . . . . . . 6. Mejorando Twig 6.1. Cmo funciona Twig? . 6.2. El analizador lxico . . 6.3. El analizador sintctico . 6.4. El compilador . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

7. Recetas 7.1. Haciendo un diseo condicional . . . . . . . . . . . . . . . . 7.2. Haciendo una inclusin dinmica . . . . . . . . . . . . . . . 7.3. Sustituyendo una plantilla que adems se extiende a s misma 7.4. Sintaxis personalizada . . . . . . . . . . . . . . . . . . . . . 7.5. Usando propiedades dinmicas de los objetos . . . . . . . . . 7.6. Accediendo al contexto del padre en bucles anidados . . . . . 7.7. Deniendo al vuelo funciones indenidas y ltros . . . . . . 7.8. Validando la sintaxis de la plantilla . . . . . . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

II

CAPTULO 1

Introduccin

Esta es la documentacin de Twig, el exible, rpido y seguro motor de plantillas para PHP. Si has estado expuesto a otros lenguajes de plantilla basados en texto, tal como Smarty, Django o Jinja, debes sentirte como en casa con Twig. Es a la vez, un amigable ambiente para el diseador y desarrollador apegado a los principios de PHP, aadiendo til funcionalidad a los entornos de plantillas. Las caractersticas clave son... Rpido: Twig compila las plantillas hasta cdigo PHP regular optimizado. El costo general en comparacin con cdigo PHP regular se ha reducido al mnimo. Seguro: Twig tiene un modo de recinto de seguridad para evaluar el cdigo de plantilla que no es conable. Esto te permite utilizar Twig como un lenguaje de plantillas para aplicaciones donde los usuarios pueden modicar el diseo de la plantilla. Flexible: Twig es alimentado por exibles analizadores lxico y sintctico. Esto permite al desarrollador denir sus propias etiquetas y ltros personalizados, y crear su propio DSL.

1.1 Requisitos previos


Twig necesita por lo menos PHP 5.2.4 para funcionar.

1.2 Instalando
Tienes varias formas de instalar Twig. Si no ests seguro qu hacer, descarga el archivo comprimido (tarball).

1.2.1 Desde la versin comprimida


1. Descarga el archivo comprimido ms reciente desde la pgina de descarga 2. Descomprime el archivo 3. Mueve los archivos a algn lugar en tu proyecto

Manual de Twig, Release 1.2.0

1.2.2 Instalando la versin de desarrollo


1. Instala desde Subversin o Git 2. Para Subversin:
svn co http://svn.twig-project.org/trunk/ twig

para Git:
git clone git://github.com/fabpot/Twig.git

1.2.3 Instalando el paquete PEAR


1. Instala PEAR 2. pear channel-discover pear.twig-project.org 3. pear install twig/Twig (o pear install twig/Twig-beta)

1.3 Uso bsico de la API


Esta seccin te ofrece una breve introduccin a la API PHP de Twig. El primer paso para utilizar Twig es registrar su cargador automtico:
require_once /ruta/a/lib/Twig/Autoloader.php; Twig_Autoloader::register();

Sustituye /ruta/a/lib/ con la ruta que utilizaste en la instalacin de Twig. Nota: Twig sigue la convencin de nombres de PEAR para sus clases, lo cual signica que puedes integrar fcilmente las clases de Twig cargndolo en tu propio cargador automtico.
$cargador = new Twig_Loader_String(); $twig = new Twig_Environment($cargador); $plantilla = $twig->loadTemplate(Hola {{ nombre }}!); $plantilla->display(array(nombre => Fabien));

Twig utiliza un cargador (Twig_Loader_String) para buscar las plantillas, y un entorno (Twig_Environment) para almacenar la conguracin. El mtodo LoadTemplate() utiliza el cargador para buscar y cargar la plantilla y devuelve un objeto plantilla (Twig_Template) que es adecuado para reproducirlo con el mtodo display(). Twig tambin viene con un cargador para el sistema de archivos:
$cargador = new Twig_Loader_Filesystem(/ruta/a/plantillas); $twig = new Twig_Environment($cargador, array( cache => /ruta/a/compilacin_de_cach, )); $plantilla = $twig->loadTemplate(index.html);

Captulo 1. Introduccin

CAPTULO 2

Twig para diseadores de plantillas

Este documento describe la sintaxis y semntica del motor de plantillas y ser muy til como referencia para quin est creando plantillas Twig.

2.1 Sinopsis
Una plantilla simplemente es un archivo de texto. Esta puede generar cualquier formato basado en texto (HTML, XML, CSV, LaTeX, etc.) No tiene una extensin especca, .html o .xml estn muy bien. Una plantilla contiene variables o expresiones, las cuales se reemplazan por valores cuando se evala la plantilla, y etiquetas que controlan la lgica de la plantilla. A continuacin mostramos una plantilla mnima que ilustra algunos conceptos bsicos. Vamos a ver los detalles ms adelante en este documento:
<!DOCTYPE html> <html lang="es"> <head> <title>Mi pgina web</title> </head> <body> <ul id="navegacion"> {% for elemento in navegacion %} <li><a href="{{ elemento.href }}">{{ elemento.titulo }}</a></li> {% endfor %} </ul> <h1>Mi pgina web</h1> {{ una_variable }} </body> </html>

Hay dos tipos de delimitadores: { % ... %} y {{ ... }}. El primero se utiliza para ejecutar declaraciones como bucles for, el ltimo imprime en la plantilla el resultado de una expresin.

Manual de Twig, Release 1.2.0

2.2 Integrando con IDEs


Los IDEs modernos son compatibles con el resaltado de sintaxis y autocompletado en una amplia gama de lenguajes. Textmate va el paquete Twig Vim va el complemento de sintaxis Jinja Netbeans va el complemento de sintaxis Twig PhpStorm (nativo a partir de 2.1) Eclipse va el complemento Twig Sublime Text va el paquete Twig GtkSourceView va el lenguaje de denicin Twig (usado por gedit y otros proyectos)

2.3 Variables
La aplicacin pasa variables a las plantillas para que puedas combinarlas en la plantilla. Las variables pueden tener atributos o elementos en ellas a los cuales puedes acceder tambin. Cmo se ve una variable, en gran medida, depende la aplicacin que la proporcione. Puedes utilizar un punto (.) para acceder a los atributos de una variable, puedes utilizar una alternativa a la as llamada sintaxis de subndice ([]). Las siguientes lneas hacen lo mismo:
{{ foo.bar }} {{ foo[bar] }}

Nota: Es importante saber que las llaves no son parte de la variable, sino de la declaracin de impresin. Si accedes a variables dentro de las etiquetas no las envuelvas con llaves. Si no existe una variable o atributo, recibirs un valor nulo (el cual puedes probar con la expresin none). Implementacin Por razones de conveniencia foo.bar hace lo siguiente en la capa PHP: Comprueba si foo es una matriz y bar es un elemento vlido; si no, y si foo es un objeto, se asegura de que bar es una propiedad vlida; si no, y si foo es un objeto, se asegura de que bar es un mtodo vlido (aunque si bar es el constructor - usa __construct() en su lugar); si no, y si foo es un objeto, se asegura de que getBar es un mtodo vlido; si no, y si foo es un objeto, se asegura de que isBar es un mtodo vlido; si no, devuelve un valor nulo. foo[bar] por otro lado, generalmente trabaja igual con una pequea diferencia en el orden: Comprueba si foo es una matriz y bar un elemento vlido, si no, devuelve un valor nulo. Usar la sintaxis alternativa tambin es til para obtener dinmicamente atributos de matrices:
foo[bar]

Nota: Si deseas conseguir un atributo dinmico en una variable, en su lugar, utiliza el atributo funcin.

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

Twig siempre hace referencia a las siguientes variables: _self: Hace referencia a la plantilla actual; _context: Hace referencia al contexto actual; _charset: Hace referencia al juego de caracteres actual.

2.4 Filtros
Los ltros pueden modicar variables. Los ltros estn separados de la variable por un smbolo de tubo (|) y pueden tener argumentos opcionales entre parntesis. Puedes encadenar mltiples ltros. La salida de un ltro se aplica al siguiente. {{ nombre|striptags|title }} por ejemplo, eliminar de nombre todas las etiquetas HTML e imprimir cada palabra con mayscula inicial. Los ltros que aceptan argumentos tienen parntesis en torno a los argumentos, tal como una llamada a funcin. En este ejemplo unir una lista con comas: {{ lista|join (, ) }}. La seccin de ltros integrados - ms adelante - describe todos los ltros integrados.

2.5 Comentarios
Para comentar parte de una lnea en una plantilla, utiliza la sintaxis de comentario {# ... #}. Esta es til para comentar partes de la plantilla para depuracin o para agregar informacin para los diseadores de otra plantilla o para ti mismo:
{# nota: desactivado en la plantilla porque ya no se utiliza {% for usuario in usuarios %} ... {% endfor %} #}

2.6 Control del espacio en blanco


Nuevo en la versin 1.1: La etiqueta de control a nivel de espacio en blanco se aadi en Twig 1.1. La primer nueva lnea despus de una etiqueta de plantilla se elimina automticamente (como en PHP). El motor de plantillas no modica el espacio en blanco, por lo tanto cada espacio en blanco (espacios, tabuladores, nuevas lneas, etc.) se devuelve sin cambios. Utiliza la etiqueta spaceless para quitar los espacios en blanco entre las etiquetas HTML:
{% spaceless %} <div> <strong>foo</strong> </div> {% endspaceless %} {# Producir <div><strong>foo</strong></div> #}

Adems de la etiqueta spaceless tambin puedes controlar los espacios en blanco a nivel de etiquetas. Al utilizar el modicador de control de los espacios en blanco en las etiquetas puedes recortar los espacios en blanco precedentes/consecuentes a cualquier tipo de etiqueta:

2.4. Filtros

Manual de Twig, Release 1.2.0

{% set valor = sin espacios %} {#- Sin espacios en blanco precedentes/consecuentes -#} {%- if true -%} {{- valor -}} {%- endif -%} {# produce sin espacios #}

El ejemplo anterior muestra el modicador de control de espacios en blanco predeterminado, y cmo lo puedes utilizar para quitar los espacios en blanco alrededor de las etiquetas. Recortar el espacio debe consumir todos los espacios en blanco a ese lado de la etiqueta. Es posible utilizar el recorte de espacios en blanco en un lado de una etiqueta:
{% set valor = sin espacios %} <li> {{- valor }} </li> {# produce <li>sin espacios </li> #}

2.7 Escapando
A veces es deseable e incluso necesario contar con que Twig omita partes que de lo contrario manejara como variables o bloques. Por ejemplo, si utilizas la sintaxis predeterminada y deseas utilizar {{ como cadena sin procesar en la plantilla y no iniciar una variable, tienes que usar un truco. La forma ms sencilla es extraer la variable del delimitador ({{) usando una expresin variable:
{{ {{ }}

Para secciones mayores tiene sentido marcar un bloque raw. Por ejemplo, para poner la sintaxis de Twig como ejemplo en una plantilla, puedes utilizar este fragmento:
{% raw %} <ul> {% for elemento in sec %} <li>{{ elemento }}</li> {% endfor %} </ul> {% endraw %}

2.8 Herencia en plantillas


La parte ms poderosa de Twig es la herencia entre plantillas. La herencia de plantillas te permite crear un esqueleto de plantilla base que contenga todos los elementos comunes de tu sitio y dene los bloques que las plantillas descendientes pueden sustituir. Suena complicado pero es muy bsico. Es ms fcil entenderlo si comenzamos con un ejemplo.

2.8.1 Plantilla base


Esta plantilla, que llamaremos base.html, dene un simple documento HTML con un esqueleto bsico que puedes utilizar para una pgina sencilla de dos columnas. Es trabajo de las plantillas descendientes rellenar los bloques vacos con contenido:

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

<!DOCTYPE html> <html lang="es"> <head> {% block head %} <link rel="stylesheet" href="estilo.css" /> <title>{% block titulo %}{% endblock %} - Mi pgina web</title> {% endblock %} </head> <body> <div id="contenido">{% block contenido %}{% endblock %}</div> <div id="piepagina"> {% block piepagina %} &copy; Copyright 2011 por <a href="http://dominio.novalido/">t</a>. {% endblock %} </div> </body> </html>

En este ejemplo, las etiquetas { % block %} denen cuatro bloques que las plantillas descendientes pueden rellenar. Todas las etiquetas bloque le dicen al motor de plantillas que una plantilla derivada puede sustituir esas porciones de la plantilla.

2.8.2 Plantilla descendiente


Una plantilla hija podra tener este aspecto:
{% extends "base.html" %} {% block titulo %}ndice{% endblock %} {% block head %} {{ parent() }} <style type="text/css"> .importante { color: #336699; } </style> {% endblock %} {% block contenido %} <h1>ndice</h1> <p class="importante"> Bienvenidos a mi impresionante pgina inicial. </p> {% endblock %}

Aqu, la clave es la etiqueta { % extends %}. Esta le dice al motor de plantillas que esta plantilla extiende otra plantilla. Cuando el sistema de plantillas evala esta plantilla, en primer lugar busca a la plantilla padre. La etiqueta extends debe ser la primera etiqueta de la plantilla. El nombre de archivo de la plantilla depende del gestor de plantillas. Por ejemplo, el Twig_Loader_Filesystem te permite acceder a otras plantillas, dando el nombre del archivo. Puedes acceder a las plantillas en subdirectorios con una barra inclinada:
{% extends "base/default.html" %}

Sin embargo, este comportamiento puede depender de la aplicacin en que se integre Twig. Ten en cuenta que debido a que la plantilla descendiente no dene el bloque piepagina, en su lugar se utiliza el valor de la plantilla padre. No puedes denir mltiples etiquetas { % block %} con el mismo nombre en la misma plantilla. Esta limitacin existe porque una etiqueta de bloque trabaja en ambas direcciones. Es decir, una etiqueta de bloque no slo proporciona un hueco para rellenar - sino que tambin dene en el padre el contenido que rellena el hueco. Si en una plantilla 2.8. Herencia en plantillas 7

Manual de Twig, Release 1.2.0

hubiera dos etiquetas { % block %} con nombres similares, el padre de esa plantilla, no sabra cual contenido de entre los bloques usar. Los nombres de bloque deben consistir de caracteres alfanumricos y guiones bajos. Los guiones no estn permitidos. No obstante, si deseas imprimir un bloque varias veces, puedes utilizar la funcin block:
<title>{% block titulo %}{% endblock %}</title> <h1>{{ block(titulo) }}</h1> {% block cuerpo %}{% endblock %}

Al igual que PHP, Twig no admite la herencia mltiple. Por lo tanto slo puedes tener una etiqueta extends por representacin.

2.8.3 Bloques padre


Es posible reproducir el contenido del bloque padre usando la funcin parent. Esta devuelve los resultados del bloque padre:
{% block barralateral %} <h3>Tabla de contenido</h3> ... {{ parent() }} {% endblock %}

2.8.4 Etiquetas de bloque nombradas


Twig te permite poner el nombre del bloque despus de la etiqueta para facilitar su lectura:
{% block barralateral %} {% block interior_barralateral %} ... {% endblock interior_barralateral %} {% endblock barralateral %}

Sin embargo, el nombre despus de la palabra endblock debe coincidir con el nombre del bloque.

2.8.5 Bloques anidados y mbito


Los bloques se pueden anidar para diseos ms complejos. Por omisin, los bloques tienen acceso a las variables del mbito externo:
{% for elemento in sec %} <li>{% block loop_elemento %}{{ elemento }}{% endblock %}</li> {% endfor %}

2.8.6 Atajos de bloque


Para los bloques con poco contenido, es posible tener una sintaxis contextual. Las siguientes construcciones hacen lo mismo:
{% block titulo %} {{ titulo_pagina|title }} {% endblock %}

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

{% block titulo titulo_pagina|title %}

2.8.7 Herencia dinmica


Twig es compatible con la herencia dinmica usando una variable como la plantilla base:
{% extends alguna_var %}

Si la variable se evala como un objeto Twig_Template, Twig la utilizar como la plantilla padre:
// { % extends boceto %} $boceto = $twig->loadTemplate(algn_boceto_de_plantilla.twig); $twig->display(plantilla.twig, array(boceto => $boceto));

Nuevo en la versin 1.2: La posibilidad de pasar un arreglo de plantillas se aadi en Twig 1.2. Tambin puedes proporcionar una lista de plantillas que comprueben su existencia. La primer plantilla que exista se utilizar como el padre:
{% extends [layout.html, base_layout.html] %}

2.8.8 Herencia condicional


De hecho, el nombre de la plantilla puede ser cualquier expresin vlida. Por lo tanto, tambin es posible hacer condicional el mecanismo de herencia:
{% extends independiente ? "minima.html" : "base.html" %}

En este ejemplo, la plantilla debe extender el boceto de plantilla minima.html si la variable independiente evala a true, o de otra manera extiende a base.html.

2.9 Importando comportamiento del contexto


De manera predeterminada se pasa el contexto actual a las plantillas incluidas. El contexto que se pasa a la plantilla incluida incorpora las variables denidas en la plantilla:
{% for caja in cajas %} {% include "reproduce_caja.html" %} {% endfor %}

La plantilla incluida reproduce_caja.html es capaz de acceder a caja.

2.10 Escapando HTML


Cuando generas HTML desde plantillas, siempre existe el riesgo de que una variable incluya caracteres que afecten el HTML resultante. Hay dos enfoques: escapar cada variable manualmente o de manera predeterminada escapar todo automticamente. Twig apoya ambos, el escape automtico est habilitado por omisin.

2.9. Importando comportamiento del contexto

Manual de Twig, Release 1.2.0

Nota: El escape automtico slo se admite si has habilitado la extensin escaper (el cual es el valor predeterminado).

2.10.1 Trabajando con el escape manual


Si est habilitado el escape manual es tu responsabilidad escapar las variables si es necesario. Qu escapar? Si tienes una variable que puede incluir cualquiera de los siguientes caracteres (>, <, & o ") tienes que escaparla a menos que la variable contenga HTML bien formado y sea de conanza. El escape trabaja entubando la variable a travs del ltro |e: {{ usuario.nombreusuario|e }}.

2.10.2 Trabajando con escape automtico


Ya sea que el escape automtico est habilitado o no, puedes marcar una seccin de una plantilla para que sea escapada o no utilizando la etiqueta autoescape:
{% autoescape true %} Todo en este bloque ser escapado automticamente {% endautoescape %} {% autoescape false %} Todo en este bloque ser reproducido tal cual {% endautoescape %} {% autoescape true js %} Todo en este bloque ser escapado automticamente usando la estrategia de escape js {% endautoescape %}

Cuando se activa el escape automtico, de manera predeterminada todo ser escapado, salvo los valores marcados explcitamente como seguros. Estos se pueden marcar en la plantilla mediante el ltro |raw. Las funciones que devuelven datos de plantilla (como macros y parent) siempre devuelven marcado seguro. Nota: Twig es lo sucientemente inteligente como para no escapar un valor que ya ha escapado el ltro escape.

Nota: El captulo para dar ms informacin a los desarrolladores acerca de cundo y cmo se aplica el escape automtico.

2.11 Lista de las estructuras de control


Una estructura de control se reere a todas esas cosas que controlan el ujo de un programa - condicionales (es decir, if/elseif/else), bucles-for, adems de cosas como los bloques. Las estructuras de control aparecern dentro de bloques { % ... %}.

2.11.1 For
Recorre cada elemento de una secuencia. Por ejemplo, para mostrar una lista de usuarios provista en una variable llamada usuarios:

10

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

<h1>Afiliados</h1> <ul> {% for usuario in usuarios %} <li>{{ usuario.nombreusuario|e }}</li> {% endfor %} </ul>

Nota: Una secuencia puede ser una matriz o un objeto que implementa la interfaz Traversable. Si necesitas iterar en una secuencia de nmeros, puedes utilizar el operador ..:
{% for i in 0..10 %} * {{ i }} {% endfor %}

El fragmento de cdigo anterior debera imprimir todos los nmeros del 0 al 10. Tambin puede ser til con letras:
{% for letra in a..z %} * {{ letra }} {% endfor %}

El operador .. puede tomar cualquier expresin en ambos lados:


{% for letra in a|upper..z|upper %} * {{ letra }} {% endfor %}

Dentro de un bloque de bucle for puedes acceder a algunas variables especiales: Variable loop.index loop.index0 loop.revindex loop.revindex0 loop.first loop.last loop.length loop.parent Descripcin La iteracin actual del bucle. (indexada en 1) La iteracin actual del bucle. (indexada en 0) El nmero de iteraciones a partir del nal del bucle (indexadas en 1) El nmero de iteraciones a partir del nal del bucle (indexadas en 0) True si es la primera iteracin True si es la ltima iteracin El nmero de elementos en la secuencia El contexto del padre

Nota: Las variables loop.length, loop.revindex, loop.revindex0 y loop.last nicamente estn disponibles para matrices PHP, u objetos que implementen la interfaz Countable. Nuevo en la versin 1.2: La compatibilidad con el modicador if se aadi en Twig 1.2. A diferencia de PHP, en un bucle no es posible usar break ni continue. Sin embargo, puedes ltrar la secuencia durante la iteracin, lo cual te permite omitir elementos. En el siguiente ejemplo se omiten todos los usuarios que no estn activos:
<ul> {% for usuario in usuarios if usuario.activo %} <li>{{ usuario.nombreusuario|e }}</li> {% endfor %} </ul>

La ventaja es que la variable especial loop contar correctamente, es decir, sin contar a los usuarios inactivos en la iteracin.

2.11. Lista de las estructuras de control

11

Manual de Twig, Release 1.2.0

Si no se llev a cabo iteracin debido a que la secuencia est vaca, puedes reproducir un bloque sustituto utilizando else:
<ul> {% for usuario in usuarios %} <li>{{ usuario.nombreusuario|e }}</li> {% else %} <li><em>no hay usuarios</em></li> {% endfor %} </ul>

De forma predeterminada, un bucle itera en los valores de la secuencia. Puedes iterar en las claves con el ltro keys:
<h1>Afiliados</h1> <ul> {% for clave in usuarios|keys %} <li>{{ clave }}</li> {% endfor %} </ul>

Tambin puedes acceder tanto a las claves como a los valores:


<h1>Afiliados</h1> <ul> {% for clave, usuario in usuarios %} <li>{{ clave }}: {{ usuario.nombreusuario|e }}</li> {% endfor %} </ul>

2.11.2 If
La declaracin if en Twig es comparable con las declaraciones if de PHP. En la forma ms simple la puedes usar para probar si una variable no est vaca:
{% if usuarios %} <ul> {% for usuario in usuarios %} <li>{{ usuario.nombreusuario|e }}</li> {% endfor %} </ul> {% endif %}

Nota: Si deseas probar si una variable est denida, usa if usuarios is defined en su lugar. Para ramicacin mltiple puedes utilizar elseif y else como en PHP. All tambin puedes utilizar expresiones ms complejas:
{% if kenny.enfermo %} Kenny est enfermo. {% elseif kenny.muerto %} Mataste a Kenny! Maldito! {% else %} Kenny se ve bien --- hasta ahora {% endif %}

12

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

2.11.3 Macros
Las macros son comparables con funciones en lenguajes de programacin regulares. Son tiles para poner modismos HTML utilizados frecuentemente en elementos reutilizables para no repetirlos. He aqu un pequeo ejemplo de una macro que reproduce un elemento de formulario:

{% macro input(nombre, valor, tipo, largo) %} <input type="{{ tipo|default(text) }}" name="{{ nombre }}" value="{{ valor|e }}" size="{{ largo {% endmacro %}

Las macros se diferencian de las funciones PHP nativas en varias formas: Los valores predeterminados de los argumentos se denen mediante el ltro default en el cuerpo de la macro; Los argumentos de una macro siempre son opcionales. Pero como las funciones de PHP, las macros no tienen acceso a las variables de la plantilla actual. Truco: Puedes pasar todo el contexto como un argumento usando la variable especial _context. Las macros se pueden denir en cualquier plantilla, y es necesario importarlas, antes de utilizarlas (consulta la seccin Importando para ms informacin):
{% import "formularios.html" as forms %}

La llamada a import anterior importa el archivo formularios.html (el cual puede contener macros solamente, o una plantilla y algunas macros), e importa las funciones como elementos de la variable forms. Entonces puedes llamar a la macro a voluntad:
<p>{{ forms.input(nombreusuario) }}</p> <p>{{ forms.input(password, none, pase) }}</p>

Si las macros son denidas y utilizadas en la misma plantilla, puedes utilizar la variable especial _self, sin necesidad de importarlas:
<p>{{ _self.input(nombreusuario) }}</p>

Cuando desees utilizar una macro en otra en el mismo archivo, utiliza la variable _self:

{ % macro input(nombre, valor, tipo, largo) %} <input type="{{ tipo|default(text) }}" name="{{ nombre }}" value="{{ valor|e }}" size="{{ largo|d { % endmacro %} { % macro input_envuenta(nombre, valor, tipo, largo) %} <div class="campo"> {{ _self.input(nombre, valor, tipo, largo) }} </div> { % endmacro %}

Cuando la macro est denida en otro archivo, necesitas importarla:


{# formularios.html #}

{% macro input(nombre, valor, tipo, largo) %} <input type="{{ tipo|default(text) }}" name="{{ nombre }}" value="{{ valor|e }}" size="{{ largo|d {% endmacro %} {# atajos.html #}

2.11. Lista de las estructuras de control

13

Manual de Twig, Release 1.2.0

{% macro input_envuenta(nombre, valor, tipo, largo) %} {% import "formularios.html" as forms %} <div class="campo"> {{ forms.input(nombre, valor, tipo, largo) }} </div> {% endmacro %}

2.11.4 Filtros
Filtrar secciones te permite aplicar ltros Twig regulares en un bloque de datos de la plantilla. Simplemente envuelve el cdigo en la seccin especial filter:
{% filter upper %} Este texto se convierte a maysculas {% endfilter %}

Tambin puedes encadenar ltros:


{% filter lower|escape %} <strong>ALGN TEXTO</strong> {% endfilter %}

Este debe devolver <strong>algn texto</strong>.

2.11.5 Asignaciones
Dentro del cdigo de los bloques tambin puedes asignar valores a variables. Las asignaciones utilizan la etiqueta set y puedes tener mltiples destinos:
{% set foo = foo %} {% set foo = [1, 2] %} {% set foo = {foo: bar} %} {% set foo = foo ~ bar %} {% set foo, bar = foo, bar %}

La etiqueta set tambin se puede usar para capturar trozos de texto:


{% set foo %} <div id="paginacion"> ... </div> {% endset %}

Prudencia: Si habilitas el escape automtico, Twig slo tendr en cuenta el contenido seguro al capturar fragmentos de texto.

2.11.6 Extends
Puedes utilizar la etiqueta extends para extender una plantilla a partir de otra. Puedes tener varias de ellas en un archivo, pero slo una de ellas se puede ejecutar al momento. No hay apoyo para herencia mltiple. Ve la seccin 14 Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

anterior sobre la herencia de plantillas para ms informacin.

2.11.7 Block
Los bloques se utilizan para la herencia y actan como marcadores de posicin y reemplazo al mismo tiempo. Estos estn documentados en detalle como parte de la seccin anterior sobre la herencia de plantillas.

2.11.8 Include
La declaracin include es til para incluir una plantilla y devolver el contenido reproducido de ese archivo en el espacio de nombres actual:
{% include cabecera.html %} Cuerpo {% include piepagina.html %}

Las plantillas incluidas tienen acceso a las variables del contexto activo. Puedes aadir variables adicionales pasndolas despus de la palabra clave with:
{# la plantilla foo tendr acceso a las variables del contexto actual y el foo uno #} {% include foo with {foo: bar} %} {% set vars = {foo: bar} %} {% include foo with vars %}

Puedes desactivar el acceso al contexto aadiendo la palabra clave only:


{# slo la variable foo ser accesible #} {% include foo with {foo: bar} only %} {# ninguna variable ser accesible #} {% include foo only %}

Truco: Cuando incluyes una plantilla creada por un usuario nal, debes considerar supervisarla. Ms informacin en el captulo Twig para desarrolladores (Pgina 27). El nombre de la plantilla puede ser cualquier expresin Twig vlida:
{% include alguna_variable %} {% include ajax ? ajax.html : no_ajax.html %}

Y si la expresin evala como un objeto Twig_Template, Twig la usar directamente:


// { % include plantilla %} $plantilla = $twig->loadTemplate(alguna_plantilla.twig); $twig->loadTemplate(plantilla.twig)->display(array(template => $plantilla));

Nuevo en la versin 1.2: La caracterstica ignore missing se aadi en Twig 1.2. Puedes marcar un include con ignore missing en cuyo caso Twig omitir la declaracin si la plantilla a ignorar no existe. Se tiene que colocar justo despus del nombre de la plantilla. He aqu algunos ejemplos vlidos:

2.11. Lista de las estructuras de control

15

Manual de Twig, Release 1.2.0

{% include "sidebar.html" ignore missing %} {% include "sidebar.html" ignore missing with {foo: bar} %} {% include "sidebar.html" ignore missing only %}

Nuevo en la versin 1.2: La posibilidad de pasar un arreglo de plantillas se aadi en Twig 1.2. Tambin puedes proporcionar una lista de plantillas para comprobar su existencia antes de la inclusin. La primer plantilla existe ser incluida:
{% include [pagina_detallada.html, pagina.html] %}

Si se le da ignore missing, caer de nuevo en reproducir nada si ninguna de las plantillas existente, de lo contrario se producir una excepcin.

2.11.9 Import
Twig apoya poner en macros el cdigo usado frecuentemente. Estas macros pueden estar en diferentes plantillas y se importan desde all. Hay dos formas de importar plantillas. Puedes importar la plantilla completa en una variable o solicitar macros especcas de ella. Imaginemos que tienes un mdulo auxiliar que reproduce formularios (llamado formularios.html):

{% macro input(nombre, valor, tipo, largo) %} <input type="{{ tipo|default(text) }}" name="{{ nombre }}" value="{{ valor|e }}" size="{{ largo {% endmacro %}

{% macro textarea(nombre, valor, filas) %} <textarea name="{{ nombre }}" rows="{{ filas|default(10) }}" cols="{{ cols|default(40) }}">{{ val {% endmacro %}

La forma ms fcil y exible es importar todo el mdulo en una variable. De esa manera puedes acceder a los atributos:
{% import formularios.html as forms %} <dl> <dt>Nombre</dt> <dd>{{ forms.input(nombreusuario) }}</dd> <dt>Contrasea</dt> <dd>{{ forms.input(password, none, pase) }}</dd> </dl> <p>{{ forms.textarea(comentario) }}</p>

Alternativamente, puedes importar nombres desde la plantilla al espacio de nombres actual:


{% from formularios.html import input as campo_input, textarea %} <dl> <dt>Nombre</dt> <dd>{{ campo_input(nombreusuario) }}</dd> <dt>Contrasea</dt> <dd>{{ campo_input(pase, type=password) }}</dd> </dl> <p>{{ textarea(comentario) }}</p>

La importacin no es necesaria si las macros y la plantilla estn denidas en el mismo archivo; en su lugar usa la variable especial _self:

16

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

{# plantilla index.html #}

{ % macro textarea(nombre, valor, filas) %} <textarea name="{{ nombre }}" rows="{{ filas|default(10) }}" cols="{{ cols|default(40) }}">{{ val { % endmacro %} <p>{{ _self.textarea(comentario) }}</p>

Pero s puedes crear un alias importando la variable _self:


{# plantilla index.html #}

{% macro textarea(nombre, valor, filas) %} <textarea name="{{ nombre }}" rows="{{ filas|default(10) }}" cols="{{ cols|default(40) }}">{{ val {% endmacro %} {% import _self as forms %} <p>{{ forms.textarea(comentario) }}</p>

2.12 Expresiones
Twig permite expresiones bsicas en cualquier parte. Estas funcionan de manera muy similar a PHP regular, e incluso si no ests trabajando con PHP debes sentirte cmodo con ellas. La precedencia de operadores es la siguiente, con los operadores de menor prioridad en primer lugar: or, and, ==, !=, <, >, >=, <=, in, +, -, ~, *, /, %, //, is, .. y **.

2.12.1 Literales
La forma ms simple de las expresiones son literales. Los literales son representaciones para tipos PHP, tal como cadenas, nmeros y matrices. Existen los siguientes literales: "Hola mundo": Todo lo que est entre comillas simples o dobles es una cadena. Son tiles cuando necesitas una cadena en la plantilla (por ejemplo, como argumentos para llamadas a funcin, ltros o simplemente para extender o incluir una plantilla). 42 / 42.23: Nmeros enteros y nmeros en coma otante se crean al slo escribir el nmero. Si est presente un punto es un nmero en coma otante, de lo contrario es un nmero entero. ["foo", "bar"]: Las matrices se denen con una secuencia de expresiones separadas por una coma (,) y envuelta con parntesis cuadrados ([]). {"foo": "bar"}: Los valores hash se denen con una lista de claves y valores separados por una coma(,) y envueltos entre llaves ({}). Un valor puede ser cualquier expresin vlida. true / false: true representa el valor verdadero, false representa el valor falso. none: none no representa ningn valor especco (el equivalente a null en PHP). Este es el valor devuelto cuando una variable no existe. Los arreglos y hashes se pueden anidar:
{% set foo = [1, {"foo": "bar"}] %}

2.12. Expresiones

17

Manual de Twig, Release 1.2.0

2.12.2 Matemticas
Twig te permite calcular valores. Esto no suele ser til en las plantillas, pero existe por el bien de la integridad. Admite los siguientes operadores: +: Suma dos objetos (los operandos se convierten a nmeros). {{ 1 + 1 }} es 2. -: Resta el segundo nmero del primero. {{ 3 - 2 }} es 1. /: Divide dos nmeros. El valor devuelto ser un nmero en coma otante. {{ 1 / 2 }} es {{ 0.5 }}. %: Calcula el resto de una divisin entera. {{ 11 % 7 }} es 4. //: Divide dos nmeros y devuelve el resultado entero truncado. {{ 20 // 7 }} es 2. *: Multiplica el operando de la izquierda con el de la derecha. {{ 2 * 2 }} devolver 4. **: Eleva el operando izquierdo a la potencia del operando derecho. {{ 2**3 }} debe devolver 8.

2.12.3 Lgica
Para declaraciones if, ltrado for o expresiones if sera til combinar mltiples expresiones: and: Devuelve true si ambos operandos izquierdo y derecho son true. or: Devuelve true si el operando izquierdo o derecho es true. not: Niega una declaracin. (expr): Agrupa una expresin.

2.12.4 Comparaciones
Los siguientes operadores de comparacin son compatibles con cualquier expresin: ==, !=, <, >, >= y <= .

2.12.5 Operador de contencin


El operador in realiza la prueba de contencin. Esta devuelve true si el operando de la izquierda gura en el de la derecha:
{# devuelve true #} {{ 1 in [1, 2, 3] }} {{ cd in abcde }}

Truco: Puedes utilizar este ltro para realizar una prueba de contencin en cadenas, arreglos u objetos que implementan la interfaz Traversable. Para llevar a cabo una prueba negativa, utiliza el operador not in:
{% if 1 not in [1, 2, 3] %} {# es equivalente a #} {% if not (1 in [1, 2, 3]) %}

18

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

2.12.6 Pruebas
El operador is realiza pruebas. Puedes utilizar las pruebas para comprobar una variable con una expresin comn. El operando de la derecha es el nombre de la prueba:
{# averigua si una variable es impar #} {{ nombre is odd }}

Las pruebas tambin pueden aceptar argumentos:


{% if loop.index is divisibleby(3) %}

Puedes negar las pruebas usando el operador not:


{% if loop.index is not divisibleby(3) %} {# es equivalente a #} {% if not (loop.index is divisibleby(3)) %}

La seccin pruebas incorporadas de la siguiente seccin describe todas las pruebas integradas.

2.12.7 Otros operadores


Los siguientes operadores son muy tiles pero no encajan en ninguna de las otras dos categoras: ..: Crea una secuencia basada en el operando antes y despus del operador (consulta la etiqueta for para ver algunos ejemplos de uso). |: Aplica un ltro. ~: Convierte todos los operandos en cadenas y los concatena. {{ "Hola " ~ nombre ~ "!" }} debera devolver (suponiendo que nombre es Juan) Hola Juan!. ., []: Obtiene un atributo de un objeto. ?:: Twig admite el operador ternario de PHP:
{{ foo ? s : no }}

2.13 Lista de ltros integrados


2.13.1 date
Nuevo en la versin 1.1: La compatibilidad con la zona horaria se aadi en Twig 1.1. El ltro date es capaz de formatear una fecha en un determinado formato:
{{ comunicado.publicado_el|date("m/d/Y") }}

El ltro date acepta cualquier formato de fecha compatible con DateTime e instancias de DateTime. Por ejemplo, para mostrar la fecha actual, ltra la palabra "now":
{{ "now"|date("m/d/Y") }}

Para escapar palabras y caracteres en el formato de fecha usa \\ al frente de cada carcter:

2.13. Lista de ltros integrados

19

Manual de Twig, Release 1.2.0

{{ comunicado.publicado_el|date("F jS \\a\\t g:ia") }}

Tambin puedes especicar una zona horaria:


{{ comunicado.publicado_el|date("m/d/Y", "Europe/Paris") }}

2.13.2 format
El ltro format ltra formatos de una cadena dada sustituyendo los marcadores de posicin (los marcadores de posicin siguen la notacin de printf):
{{ "Me gustan %s y %s."|format(foo, "bar") }} {# devuelve Me gustan foo y bar. (si el parmetro foo es igual a la cadena foo) #}

2.13.3 replace
El ltro reemplaza formatos de una cadena dada sustituyendo los marcadores de posicin (los marcadores de posicin son libres):
{{ "Me gustan %esto% y %aquello%."|replace({%esto%: foo, %aquello%: "bar"}) }} {# devuelve Me gustan foo y bar. (si el parmetro foo es igual a la cadena foo) #}

2.13.4 url_encode
El url_encode ltra una cadena URL codicada.

2.13.5 json_encode
El ltro json_encode devuelve la representacin JSON de una cadena.

2.13.6 title
El ltro title devuelve una versin con maysculas iniciales del valor. Es decir, las palabras deben empezar con letras maysculas, todos los caracteres restantes son minsculas.

2.13.7 capitalize
El ltro capitalize capitaliza un valor. El primer carcter ser en mayscula, los otros en minsculas.

2.13.8 upper
El ltro upper convierte un valor a maysculas.

2.13.9 lower
El ltro lower convierte un valor a minsculas. 20 Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

2.13.10 striptags
El ltro striptags quita etiquetas SGML/XML y sustituye los espacios en blanco adyacentes por un espacio.

2.13.11 join
El ltro join devuelve una cadena que es la concatenacin de las cadenas en la secuencia. El separador predeterminado entre los elementos es una cadena vaca, lo puedes denir con el parmetro opcional:
{{ [1, 2, 3]|join(|) }} {# devuelve 1|2|3 #} {{ [1, 2, 3]|join }} {# devuelve 123 #}

2.13.12 reverse
El ltro reverse invierte una matriz o un objeto si implementa la interfaz Iterator.

2.13.13 length
El ltro length devuelve el nmero de elementos de una secuencia o asignacin, o la longitud de una cadena.

2.13.14 sort
El ltro sort ordena una matriz.

2.13.15 default
El ltro default devuelve el valor pasado como predeterminado si el valor no es denido o est vaco, de lo contrario devuelve el valor de la variable:
{{ var|default(var no est definido) }} {{ var.foo|default(el elemento foo en var no est definido) }} {{ |default(la variable pasada est vaca) }}

Nota: Lee ms adelante la documentacin de las pruebas defined y empty para aprender ms acerca de su semntica.

2.13.16 keys
El ltro keys devuelve las claves de una matriz. Es til cuando deseas iterar sobre las claves de una matriz:
{% for clave in arreglo|keys %} ... {% endfor %}

2.13. Lista de ltros integrados

21

Manual de Twig, Release 1.2.0

2.13.17 escape, e
El ltro escape convierte los caracteres &, <, >, y " a cadenas y secuencias HTML seguras. Utiliza esta opcin si necesitas mostrar texto que puede contener tales caracteres HTML. Nota: Internamente, escape utiliza la funcin htmlspecialchars de PHP.

2.13.18 raw
El ltro raw marca el valor como seguro lo cual signica que en un ambiente con escape automtico activado esta variable no se escapar, si raw es el ltimo ltro aplicado.
{% autoescape true %} {{ var|raw }} {# var no se escap #} {% endautoescape %}

2.13.19 merge
El ltro merge combina una matriz o un hash con el valor:
{% set elementos = { manzana: fruta, naranja: fruta } %} {% set elementos = elementos|merge({ peugeot: carro }) %} {# elemento ahora contiene { manzana: fruta, naranja: fruta, peugeot: carro } #}

2.14 Lista de pruebas incorporadas


2.14.1 divisibleby
divisibleby comprueba si una variable es divisible por un nmero:
{% if loop.index is divisibleby(3) %}

2.14.2 none
none devuelve true si la variable es none:
{{ var is none }}

2.14.3 even
even devuelve true si el nmero dado es par:
{{ var is even }}

22

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

2.14.4 odd
odd devuelve true si el nmero dado es impar:
{{ var is odd }}

2.14.5 sameas
sameas comprueba si una variable apunta a la misma direccin de memoria que otra variable:
{% if foo.atributo is sameas(false) %} el atributo foo en realidad es el valor false de PHP {% endif %}

2.14.6 constant
constant comprueba si una variable tiene el mismo valor exacto que una constante. Puedes utilizar cualquiera de las constantes globales o constantes de clase:
{% if comunicado.estado is constant(Comunicado::PUBLISHED) %} el atributo estatus es exactamente el mismo que Comunicado::PUBLISHED {% endif %}

2.14.7 defined
defined comprueba si una variable est denida en el contexto actual. Esto es muy til si utilizas la opcin strict_variables:
{# defined trabaja con nombres de variable #} {% if foo is defined %} ... {% endif %} {# y atributos en nombres de variables #} {% if foo.bar is defined %} ... {% endif %}

2.14.8 empty
empty comprueba si una variable est vaca:
{# evala a true si la variable foo es null, false o la cadena vaca #} {% if foo is empty %} ... {% endif %}

2.15 Lista de funciones globales


De forma predeterminada, las siguientes funciones estn disponibles en el mbito global:

2.15. Lista de funciones globales

23

Manual de Twig, Release 1.2.0

2.15.1 range
Devuelve una lista con una progresin aritmtica de enteros. Cuando se da el paso, este especica el incremento (o decremento):
{% for i in range(0, 3) %} {{ i }}, {% endfor %} {# devuelve 0, 1, 2, 3 #} {% for i in range(0, 6, 2) %} {{ i }}, {% endfor %} {# devuelve 0, 2, 4, 6 #}

Truco: La funcin range trabaja como la funcin range nativa de PHP. El operador .. es azcar sintctica para la funcin range (con un paso de 1):
{% for i in 0..10 %} {{ i }}, {% endfor %}

2.15.2 cycle
Puedes utilizar la funcin cycle para recorrer un arreglo de valores:
{% for i in 0..10 %} {{ cycle([odd, even], i) }} {% endfor %}

La matriz puede contener cualquier cantidad de valores:


{% set frutas = [manzana, naranja, ctricos] %} {% for i in 0..10 %} {{ cycle(frutas, i) }} {% endfor %}

2.15.3 constant
constant devuelve el valor constante de una determinada cadena:
{{ alguna_fecha|date(constant(DATE_W3C)) }}

2.15.4 attribute
Nuevo en la versin 1.2: La funcin attribute se aadi en Twig 1.2. puedes usar attribute para acceder a los atributos dinmicos de una variable:

24

Captulo 2. Twig para diseadores de plantillas

Manual de Twig, Release 1.2.0

{{ attribute(objeto, mtodo) }} {{ attribute(objeto, mtodo, argumentos) }} {{ attribute(array, elemento) }}

Nota: El algoritmo de resolucin es el mismo que el utilizado para la notacin de punto (.), salvo que el elemento puede ser cualquier expresin vlida.

2.16 Extendiendo
Puedes extender Twig fcilmente. Si ests buscando nuevas etiquetas o ltros, echa un vistazo al repositorio de extensiones ocial de Twig: http://github.com/fabpot/Twig-extensions.

2.17 Reutilizacin horizontal


Nuevo en la versin 1.1: La reutilizacin horizontal se aadi en Twig 1.1. Nota: La reutilizacin horizontal es una caracterstica avanzada de Twig que casi nunca es necesaria en plantillas regulares. Lo utilizan principalmente proyectos que tienen que reutilizar bloques de plantilla sin utilizar herencia. La herencia de plantillas es una de las ms poderosas caractersticas de Twig, pero est limitada a herencia simple; una plantilla slo puede extender una plantilla ms. Esta limitacin facilita el entendimiento y depuracin de la herencia de plantillas:
{% extends "base.html" %} {% block titulo %}{% endblock %} {% block contenido %}{% endblock %}

La reutilizacin horizontal es una forma de conseguir el mismo objetivo que la herencia mltiple, pero sin la complejidad asociada:
{% extends "base.html" %} {% use "bloques.html" %} {% block titulo %}{% endblock %} {% block contenido %}{% endblock %}

La declaracin use dice a Twig que importe los bloques denidos en bloques.html en la plantilla actual (es como las macros, pero para bloques):
# bloques.html {% block barralateral %}{% endblock %}

En este ejemplo, la declaracin use importa la declaracin del bloque barralateral en la plantilla principal. El cdigo - en su mayora - es equivalente a lo siguiente (los bloques importados no se generan automticamente):
{% extends "base.html" %} {% block barralateral %}{% endblock %} {% block titulo %}{% endblock %} {% block contenido %}{% endblock %}

2.16. Extendiendo

25

Manual de Twig, Release 1.2.0

Nota: La etiqueta use slo importa una plantilla si esta: no extiende a otra plantilla no dene macros, y si el cuerpo est vaco. Pero puedes usar otras plantillas.

Nota: Debido a que las declaraciones use se resuelven independientemente del contexto pasado a la plantilla, la referencia de la plantilla no puede ser una expresin. La plantilla principal tambin puede sustituir cualquier bloque importado. Si la plantilla ya dene el bloque barralateral, entonces, se ignora el denido en bloques.html. Para evitar conictos de nombre, puedes cambiar el nombre de los bloques importados:
{% extends "base.html" %} {% use "bloques.html" with barralateral as barralateral_base %} {% block barralateral %}{% endblock %} {% block titulo %}{% endblock %} {% block contenido %}{% endblock %}

Al renombrar tambin te permite simular la herencia llamando al bloque padre (como si lo hubieras hecho con parent()):
{% extends "base.html" %} {% use "bloques.html" with barralateral_base as barralateral_padre %} {% block barralateral %} {{ block(barralateral_padre) }} {% endblock %} {% block titulo %}{% endblock %} {% block contenido %}{% endblock %}

Nota: Puedes utilizar tantas instrucciones use como quieras en cualquier plantilla determinada. Si dos plantillas importadas denen el mismo bloque, el ltimo gana.

26

Captulo 2. Twig para diseadores de plantillas

CAPTULO 3

Twig para desarrolladores

Este captulo describe la API para Twig y no el lenguaje de plantillas. Ser muy til como referencia para aquellos que implementan la interfaz de plantillas para la aplicacin y no para los que estn creando plantillas Twig.

3.1 Fundamentos
Twig utiliza un objeto central llamado el entorno (de la clase Twig_Environment). Las instancias de esta clase se utilizan para almacenar la conguracin y extensiones, y se utilizan para cargar plantillas del sistema de archivos o en otros lugares. La mayora de las aplicaciones debe crear un objeto Twig_Environment al iniciar la aplicacin y usarlo para cargar plantillas. En algunos casos, sin embargo, es til disponer de mltiples entornos lado a lado, si las distintas conguraciones estn en uso. La forma ms sencilla de congurar Twig para cargar plantillas para tu aplicacin se ve ms o menos as:
require_once /ruta/a/lib/Twig/Autoloader.php; Twig_Autoloader::register(); $cargador = new Twig_Loader_Filesystem(/ruta/a/plantillas); $twig = new Twig_Environment($cargador, array( cache => /ruta/a/compilacin_de_cach, ));

Esto crear un entorno de plantillas con la conguracin predeterminada y un cargador que busca las plantillas en el directorio /ruta/a/plantillas/. Hay diferentes cargadores disponibles y tambin puedes escribir el tuyo si deseas cargar plantillas de una base de datos u otros recursos. Nota: Ten en cuenta que el segundo argumento del entorno es una matriz de opciones. La opcin cache es un directorio de cach de compilacin, donde Twig memoriza las plantillas compiladas para evitar la fase de anlisis de las subsiguientes peticiones. Esta es muy diferente de la cach que posiblemente desees agregar para evaluar plantillas. Para tal necesidad, puedes utilizar cualquier biblioteca de cach PHP disponible. Para cargar una plantilla desde este entorno slo tienes que llamar al mtodo LoadTemplate() el cual devuelve una instancia de Twig_Template:

27

Manual de Twig, Release 1.2.0

$plantilla = $twig->loadTemplate(index.html);

Para reproducir la plantilla con algunas variables, llama al mtodo render():


echo $plantilla->render(array(las => variables, ir => aqu));

Nota: El mtodo display() es un atajo para reproducir la plantilla directamente.

3.2 Opciones del entorno


Al crear una nueva instancia de Twig_Environment, puedes pasar una matriz de opciones como segundo argumento del constructor:
$twig = new Twig_Environment($cargador, array(debug => true));

Las siguientes opciones estn disponibles: debug: Cuando se establece en true, las plantillas generadas tienen un mtodo __toString() que puedes utilizar para mostrar los nodos generados (el predeterminado es false). charset: El juego de caracteres usado por las plantillas (por omisin a utf-8). base_template_class: La clase de plantilla base utilizada para generar plantillas (por omisin Twig_Template). cache: Una ruta absoluta donde almacenar las plantillas compiladas, o false para desactivar el almacenamiento en cach (el cual es el valor predeterminado). auto_reload: Cuando desarrollas con Twig, es til volver a compilar la plantilla cada vez que el cdigo fuente cambia. Si no proporcionas un valor para la opcin auto_reload, se determinar automticamente en funcin del valor debug. strict_variables: Si se establece en false, Twig ignorar silenciosamente las variables no vlidas (variables y/o atributos/mtodos que no existen) y los reemplazar con un valor null. Cuando se establece en true, Twig produce una excepcin en su lugar (el predeterminado es false). autoescape: Si se establece en true, el escape automtico ser habilitado de manera predeterminada para todas las plantillas (por omisin a true). optimizations: Una marca que indica cuales optimizaciones aplicar (por omisin a -1 todas las optimizaciones estn habilitadas, para desactivarlo ponlo a 0).

3.3 Cargadores
Los cargadores son responsables de cargar las plantillas desde un recurso como el sistema de archivos.

3.3.1 Cach de compilacin


Todos los cargadores de plantillas en cache pueden compilar plantillas en el sistema de archivos para su futura reutilizacin. Esto acelera mucho cmo se compilan una sola vez las plantillas Twig, y el aumento del rendimiento es an mayor si utilizas un acelerador PHP como APC. Consulta las opciones anteriores cache y auto_reload de Twig_Environment para ms informacin.

28

Captulo 3. Twig para desarrolladores

Manual de Twig, Release 1.2.0

3.3.2 Cargadores integrados


Aqu est una lista de los cargadores incorporados de que dispone Twig: Twig_Loader_Filesystem: Carga las plantillas desde el sistema de archivos. Este cargador puede encontrar plantillas en los directorios del sistema de archivos y es la manera preferida de cargarlas:
$cargador = new Twig_Loader_Filesystem($dirPlantillas);

Tambin puedes buscar plantillas en una matriz de directorios:


$cargador = new Twig_Loader_Filesystem(array($dirPlantillas1, $dirPlantillas2));

Con esta conguracin, Twig buscar primero las plantillas de $dirPlantillas1 y si no existen, regresar a buscar en $dirPlantillas2. Twig_Loader_String: Carga plantillas desde una cadena. Es un cargador silencioso que va cargando el cdigo fuente directamente a medida que se lo vas pasando:
$cargador = new Twig_Loader_String();

Twig_Loader_Array: Carga una plantilla a partir de una matriz PHP. Se le pasa una matriz de cadenas vinculadas a los nombres de plantilla. Este cargador es til para pruebas unitarias:
$cargador = new Twig_Loader_Array($plantillas);

Truco: Cuando utilices los cargadores de matriz o cadena con un mecanismo de cach, debes saber que se genera una nueva clave de cach cada vez que cambia el contenido de una plantilla (la clave de cach es el cdigo fuente de la plantilla). Si no deseas ver que tu cach crezca fuera de control, es necesario tener cuidado de limpiar el archivo de cach antiguo en s mismo.

3.3.3 Creando tu propio cargador


Todos los cargadores implementan la interfaz Twig_LoaderInterface:
interface Twig_LoaderInterface { /** * Obtiene el cdigo fuente de una plantilla, del nombre dado. * * @param string $nombre El nombre de la plantilla a cargar * * @return string El cdigo fuente de la plantilla */ function getSource($nombre); /** * Obtiene la clave de la cach para usarla en un nombre de plantilla dado. * * @param string $nombre El nombre de la plantilla a cargar * * @return string La clave de la cach */ function getCacheKey($nombre); /** * Devuelve true si la plantilla an est fresca.

3.3. Cargadores

29

Manual de Twig, Release 1.2.0

* $nombre El nombre de la plantilla * @param string * @param timestamp $time Hora de la ltima modificacin de la plantilla en cach */ function isFresh($nombre, $time); }

A modo de ejemplo, esto es lo que dice el Twig_Loader_String incorporado:


class Twig_Loader_String implements Twig_LoaderInterface { public function getSource($nombre) { return $nombre; } public function getCacheKey($nombre) { return $nombre; } public function isFresh($nombre, $time) { return false; } }

El mtodo isFresh() debe devolver true si la plantilla actual en cach an es fresca, dado el tiempo de la ltima modicacin, o false de lo contrario.

3.4 Usando extensiones


Las extensiones Twig son paquetes que aaden nuevas caractersticas a Twig. Usar una extensin es tan simple como usar el mtodo addExtension():
$twig->addExtension(new Twig_Extension_Sandbox());

Twig viene con las siguientes extensiones: Twig_Extension_Core: Dene todas las caractersticas bsicas de Twig. Twig_Extension_Escaper: Agrega escape automtico y la posibilidad de escapar/no escapar bloques de cdigo. Twig_Extension_Sandbox: Agrega un modo de recinto para el entorno predeterminado de Twig, el cual es seguro para evaluar cdigo que no es de conanza. Twig_Extension_Optimizer: Optimiza el nodo del rbol antes de la compilacin. El ncleo, las extensiones del mecanismo de escape y optimizacin no es necesario aadirlas al entorno Twig, debido a que se registran de forma predeterminada. Puedes desactivar una extensin registrada:
$twig->removeExtension(escaper);

3.5 Extensiones incorporadas


Esta seccin describe las caractersticas agregadas por las extensiones incorporadas.

30

Captulo 3. Twig para desarrolladores

Manual de Twig, Release 1.2.0

Truco: Lee el captulo sobre la ampliacin de Twig para que veas cmo crear tus propias extensiones.

3.5.1 Extensin core


La extensin core dene todas las caractersticas principales de Twig: Etiquetas: for if extends include block filter macro import from set spaceless Filtros: date format replace url_encode json_encode title capitalize upper lower striptags join reverse length sort merge default keys

3.5. Extensiones incorporadas

31

Manual de Twig, Release 1.2.0

escape e Funciones: range constant cycle parent block Pruebas: even odd defined sameas none divisibleby constant empty

3.5.2 Extensin escaper


La extensin escaper aade a Twig el escape automtico de la salida. Esta dene una nueva etiqueta, autoescape, y un nuevo ltro, raw. Al crear la extensin escaper, puedes activar o desactivar la estrategia de escape global de la salida:
$escaper = new Twig_Extension_Escaper(true); $twig->addExtension($escaper);

Si se establece en true, se escapan todas las variables en las plantillas, excepto las que utilizan el ltro raw:
{{ articulo.para_html|raw }}

Tambin puedes cambiar el modo de escape a nivel local usando la etiqueta autoescape:
{% autoescape true %} {% var %} {% var|raw %} {# var no se escapa #} {% var|escape %} {# var no se escapa doblemente #} {% endautoescape %}

Advertencia: La etiqueta autoescape no tiene ningn efecto sobre los archivos incluidos. Las reglas de escape se implementan de la siguiente manera: Literales (enteros, booleanos, matrices, ...) utilizados en la plantilla directamente como variables o argumentos de ltros no son escapados automticamente:

32

Captulo 3. Twig para desarrolladores

Manual de Twig, Release 1.2.0

{{ "Twig<br />" }} {# no se escapa #} {% set texto = "Twig<br />" %} {{ texto }} {# se deber escapar #}

Expresiones cuyo resultado siempre es un literal o una variable marcada como segura nunca sern escapadas automticamente:
{{ foo ? "Twig<br />" : "<br />Twig" }} {# no ser escapada #} { % set texto = "Twig<br />" %} {{ foo ? texto : "<br />Twig" }} {# se deber escapar #} { % set texto = "Twig<br />" %} {{ foo ? texto|raw : "<br />Twig" }} {# no ser escapada #} { % set texto = "Twig<br />" %} {{ foo ? texto|escape : "<br />Twig" }} {# el resultado de la expresin no ser escapado #}

El escape se aplica antes de la impresin, despus de haber aplicado cualquier otro ltro:
{{ var|upper }} {# es equivalente a {{ var|upper|escape }} #}

El ltro raw slo se debe utilizar al nal de la cadena de ltros:


{{ var|raw|upper }} {# se deber escapar #} {{ var|upper|raw }} {# no ser escapado #}

No se aplica el escape automtico si el ltimo ltro de la cadena est marcado como seguro para el contexto actual (por ejemplo, html o js). escaper y escaper(html) estn marcados como seguros para html, escaper(js) est marcado como seguro para javascript, raw est marcado como seguro para todo.
{% {{ {{ {{ {% autoescape true js %} var|escape(html) }} {# se deber escapar para html y javascript #} var }} {# se deber escapar para javascript #} var|escape(js) }} {# no ser escapado doblemente #} endautoescape %}

Nota: Ten en cuenta que el escape automtico tiene algunas limitaciones puesto que el escapado se aplica en las expresiones despus de su evaluacin. Por ejemplo, cuando trabajas en concatenacin, {{foo|raw ~ bar }} no dar el resultado esperado ya que el escape se aplica sobre el resultado de la concatenacin y no en las variables individuales (por lo tanto aqu, el ltro raw no tendr ningn efecto).

3.5.3 Extensin sandbox


La extensin sandbox se puede utilizar para evaluar cdigo no conable. El acceso a los atributos y los mtodos inseguros est prohibido. El entorno limitado de seguridad es manejado por una poltica de la instancia. De forma predeterminada, Twig viene con una sola clase poltica: Twig_Sandbox_SecurityPolicy. Esta clase te permite agregar a la lista blanca algunas etiquetas, ltros, propiedades y mtodos:
$etiquetas = array(if); $filtros = array(upper); $metodos = array( Artculo => array(getTitulo, getCuerpo),

3.5. Extensiones incorporadas

33

Manual de Twig, Release 1.2.0

); $propiedades = array( Articulo => array(titulo, cuerpo), ); $funciones = array(range); $politica = new Twig_Sandbox_SecurityPolicy($etiquetas, $filtros, $metodos, $propiedades, $funciones)

Con la conguracin anterior, la poltica de seguridad slo te permitir usar los ltros if, tag y upper. Por otra parte, las plantillas slo podrn llamar a los mtodos getTitulo() y getCuerpo() en objetos Artculo, y a las propiedades pblicas ttulo y cuerpo. Todo lo dems no est permitido y se generar una excepcin Twig_Sandbox_SecurityError. El objeto poltica es el primer argumento del constructor del recinto de seguridad:
$recinto = new Twig_Extension_Sandbox($politica); $twig->addExtension($recinto);

De forma predeterminada, el modo de recinto de seguridad est desactivado y se activa cuando se incluye cdigo de plantilla que no es de conanza usando la etiqueta sandbox:
{% sandbox %} {% include usuario.html %} {% endsandbox %}

Puedes poner todas las plantillas en el recinto de seguridad pasando true como segundo argumento al constructor de la extensin:
$recinto = new Twig_Extension_Sandbox($politica, true);

3.5.4 Extensin optimizer


La extensin optimizer optimiza el nodo del rbol antes de compilarlo:
$twig->addExtension(new Twig_Extension_Optimizer());

Por omisin, todas las optimizaciones estn activadas. Puedes seleccionar las que desees habilitar pasndolas al constructor:
$optimizador = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR); $twig->addExtension($optimizador);

3.6 Excepciones
Twig puede lanzar excepciones: Twig_Error: La excepcin base para todos los errores. Twig_Error_Syntax: Lanzada para indicar al usuario que hay un problema con la sintaxis de la plantilla. Twig_Error_Runtime: Lanzada cuando se produce un error en tiempo de ejecucin (cuando un ltro no existe, por ejemplo). Twig_Error_Loader: Se lanza cuando se produce un error durante la carga de la plantilla. Twig_Sandbox_SecurityError: Se lanza cuando aparece una etiqueta, ltro, o se llama a un mtodo no permitido en una plantilla de un recinto de seguridad. 34 Captulo 3. Twig para desarrolladores

CAPTULO 4

Extendiendo Twig

Twig se puede extender en muchos aspectos; puedes aadir etiquetas adicionales, ltros, pruebas, operadores, variables globales y funciones. Incluso puedes extender el propio analizador con visitantes de nodo. Nota: Este captulo describe cmo extender Twig fcilmente. Si deseas reutilizar tus cambios en diferentes proyectos o si quieres compartirlos con los dems, entonces, debes crear una extensin tal como se describe en el siguiente captulo. Antes de extender Twig, debes entender las diferencias entre todos los diferentes puntos de extensin posibles y cundo utilizarlos. En primer lugar, recuerda que el lenguaje de Twig tiene dos construcciones principales: {{ }}: Utilizada para imprimir el resultado de la evaluacin de la expresin; { % %}: Utilizada para ejecutar declaraciones. Para entender por qu Twig expone tantos puntos de extensin, vamos a ver cmo implementar un generador Lorem ipsum (este necesita saber el nmero de palabras a generar). Puedes utilizar una etiqueta Lipsum:
{% lipsum 40 %}

Eso funciona, pero usar una etiqueta para lipsum no es una buena idea por al menos tres razones principales: lipsum no es una construccin del lenguaje; La etiqueta produce algo; La etiqueta no es exible ya que no la puedes utilizar en una expresin:
{{ algn texto ~ { % lipsum 40 %} ~ algo ms de texto }}

De hecho, rara vez es necesario crear etiquetas; y es una muy buena noticia porque las etiquetas son el punto de extensin ms complejo de Twig. Ahora, vamos a utilizar un ltro lipsum:
{{ 40|lipsum }}

Una vez ms, funciona, pero se ve raro. Un ltro transforma el valor que se le pasa a alguna otra cosa, pero aqu utilizamos el valor para indicar el nmero de palabras a generar. 35

Manual de Twig, Release 1.2.0

En seguida, vamos a utilizar una funcin lipsum:


{{ lipsum(40) }}

Aqu vamos. Para este ejemplo concreto, la creacin de una funcin es el punto de extensin a usar. Y la puedes usar en cualquier lugar en que se acepte una expresin:
{{ algn texto ~ lipsum(40) ~ algo ms de texto }} {% set lipsum = lipsum(40) %}

Por ltimo pero no menos importante, tambin puedes utilizar un objeto global con un mtodo capaz de generar texto Lorem Ipsum:
{{ texto.lipsum(40) }}

Como regla general, utiliza funciones para las caractersticas ms utilizadas y objetos globales para todo lo dems. Ten en cuenta lo siguiente cuando desees extender Twig: Qu? macro global function lter tag test operator dicultad para implementacin? trivial trivial trivial trivial complejo trivial trivial Con qu frecuencia? frecuente frecuente frecuente frecuente raro raro raro Cundo? Generacin de contenido Objeto ayudante Generacin de contenido Transformacin de valor Constructor del lenguaje DSL Decisin booleana Transformacin de valores

4.1 Globales
Una variable global es como cualquier otra variable de plantilla, excepto que est disponible en todas las plantillas y macros:
$twig = new Twig_Environment($cargador); $twig->addGlobal(texto, new Text());

Entonces puedes utilizar la variable texto en cualquier parte de una plantilla:


{{ texto.lipsum(40) }}

4.2 Filtros
Un ltro es una funcin PHP regular o un mtodo de objeto que toma el lado izquierdo del ltro (antes del tubo |) como primer argumento y los argumentos adicionales pasados al ltro (entre parntesis ()) como argumentos adicionales. La denicin de un ltro es tan fcil como asociar el nombre del ltro con un ejecutable de PHP. Por ejemplo, digamos que tienes el siguiente cdigo en una plantilla:
{{ TWIG|lower }}

Al compilar esta plantilla para PHP, Twig busca el ejecutable PHP asociado con el ltro lower. El ltro lower es un ltro integrado en Twig, y simplemente se asigna a la funcin PHP strtolower(). Despus de la compilacin, el cdigo generado por PHP es ms o menos equivalente a:

36

Captulo 4. Extendiendo Twig

Manual de Twig, Release 1.2.0

<?php echo strtolower(TWIG) ?>

Como puedes ver, la cadena TWIG se pasa como primer argumento a la funcin de PHP. Un ltro tambin puede tomar argumentos adicionales como en el siguiente ejemplo:
{{ now|date(d/m/Y) }}

En este caso, los argumentos adicionales son pasadosa la funcin despus del argumento principal, y el cdigo compilado es equivalente a:
<?php echo twig_date_format_filter($now, d/m/Y) ?>

Vamos a ver cmo crear un nuevo ltro. En esta seccin, vamos a crear un ltro rot13, el cual debe devolver la transformacin rot13 de una cadena. Aqu est un ejemplo de su uso y los resultados esperados:
{{ "Twig"|rot13 }} {# debera mostrar Gjvt #}

Agregar un ltro es tan sencillo como llamar al mtodo addFilter() en la instancia de Twig_Environment:
$twig = new Twig_Environment($cargador); $twig->addFilter(rot13, new Twig_Filter_Function(rot13));

El segundo argumento de addFilter() es una instancia de Twig_Filter. Aqu, utilizamos Twig_Filter_Function puesto que el ltro es una funcin PHP. El primer argumento pasado al constructor Twig_Filter_Function es el nombre de la funcin PHP a llamar, aqu str_rot13, una funcin nativa de PHP. Digamos que ahora deseas poder aadir un prejo antes de la cadena convertida:
{{ "Twig"|rot13(prefijo_) }} {# debe mostrar prefijo_Gjvt #}

Como la funcin str_rot13() de PHP no es compatible con este requisito, vamos a crear una nueva funcin PHP:
function proyecto_calcula_rot13($cadena, $prefijo = ) { return $prefijo.str_rot13($cadena); }

Como puedes ver, el argumento prefijo del ltro se pasa como un argumento adicional a la funcin proyecto_calcula_rot13(). La adicin de este ltro es tan fcil como antes:
$twig->addFilter(rot13, new Twig_Filter_Function(proyecto_calcula_rot13));

Para una mejor encapsulacin, tambin puedes denir un ltro como un mtodo esttico de una clase. Tambin puedes utilizar la clase Twig_Filter_Function para registrar mtodos estticos, tal como ltros:
$twig->addFilter(rot13, new Twig_Filter_Function(AlgunaClase::filtroRot13));

Truco: En una extensin, tambin puedes denir un ltro como un mtodo esttico de la clase extendida.

4.2. Filtros

37

Manual de Twig, Release 1.2.0

4.2.1 Entorno consciente de ltros


La clase Twig_Filter toma opciones como su ltimo argumento. Por ejemplo, si deseas acceder a la instancia del entorno actual en tu ltro, establece la opcin needs_environment a true:
$filtro = new Twig_Filter_Function(str_rot13, array(needs_environment => true));

Twig entonces pasar el entorno actual como primer argumento al invocar el ltro:
function twig_compute_rot13(Twig_Environment $env, $cadena) { // obtiene el juego de caracteres actual, por ejemplo $charset = $env->getCharset(); return str_rot13($cadena); }

4.2.2 Escapando automticamente


Si est habilitado el escape automtico, puedes escapar la salida del ltro antes de imprimir. Si tu ltro acta como un escaper (o explcitamente produce cdigo html o javascript), desears que se imprima la salida cruda. En tal caso, establece la opcin is_safe:
$filtro = new Twig_Filter_Function(nl2br, array(is_safe => array(html)));

Algunos ltros posiblemente tengan que trabajar en valores ya escapados o seguros. En tal caso, establece la opcin pre_escape:

$filtro = new Twig_Filter_Function(algunfiltro, array(pre_escape => html, is_safe => array(h

4.3 Funciones
Una funcin es una funcin PHP regular o un mtodo de objeto que puedes llamar desde las plantillas.
{{ constant("DATE_W3C") }}

Al compilar esta plantilla para PHP, Twig busca el PHP ejecutable asociado con la funcin constant. La funcin constant est integrada en la funcin Twig, y simplemente asignada a la funcin constant() de PHP. Despus de la compilacin, el cdigo generado por PHP es ms o menos equivalente a:
<?php echo constant(DATE_W3C) ?>

Agregar una funcin es similar a agregar un ltro. Esto se puede hacer llamando al mtodo addFunction() en la instancia de Twig_Environment:
$twig = new Twig_Environment($cargador); $twig->addFunction(nombreFuncion, new Twig_Function_Function(algunaFuncin));

Tambin puedes exponer los mtodos de extensin como funciones en tus plantillas:
// $this es un objeto que implementa a Twig_ExtensionInterface. $twig = new Twig_Environment($cargador); $twig->addFunction(otrafuncion, new Twig_Function_Method($this, algnMtodo));

Las funciones tambin son compatibles con los parmetros needs_environment e is_safe.

38

Captulo 4. Extendiendo Twig

Manual de Twig, Release 1.2.0

4.4 Etiquetas
Una de las caractersticas ms interesantes de un motor de plantillas como Twig es la posibilidad de denir nuevas construcciones del lenguaje. Esta tambin es la caracterstica ms compleja que necesitas comprender de cmo trabaja Twig internamente. Vamos a crear una simple etiqueta set que te permita denir variables simples dentro de una plantilla. Puedes utilizar la etiqueta de la siguiente manera:
{% set nombre = "valor" %} {{ nombre }} {# debe sacar el valor #}

Nota: La etiqueta set es parte de la extensin core y como tal siempre est disponible. La versin integrada es un poco ms potente y de manera predeterminada es compatible con mltiples asignaciones (consulta el captulo Twig para diseadores de plantillas (Pgina 3) para ms informacin). para denir una nueva etiqueta son necesarios tres pasos: Denir una clase para analizar segmentos (responsable de analizar el cdigo de la plantilla); Denir una clase Nodo (responsable de convertir el cdigo analizado a PHP); Registrar la etiqueta.

4.4.1 Registrando una nueva etiqueta


Agregar una etiqueta es tan simple como una llamada al mtodo addTokenParser en la instancia de Twig_Environment:
$twig = new Twig_Environment($cargador); $twig->addTokenParser(new Project_Set_TokenParser());

4.4.2 Deniendo un analizador de fragmentos


Ahora, vamos a ver el cdigo real de esta clase:
class Project_Set_TokenParser extends Twig_TokenParser { public function parse(Twig_Token $token) { $lineno = $token->getLine(); $nombre = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(); $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, =); $valor = $this->parser->getExpressionParser()->parseExpression(); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); return new Project_Set_Node($nombre, $valor, $lineno, $this->getTag()); } public function getTag() {

4.4. Etiquetas

39

Manual de Twig, Release 1.2.0

return set; } }

El mtodo getTag() debe devolver la etiqueta que queremos analizar, aqu set. El mtodo parse() se invoca cada vez que el analizador encuentra una etiqueta set. Este debe devolver una instancia de Twig_Node que representa el nodo (la llamada para la creacin del Project_Set_Node se explica en la siguiente seccin). El proceso de anlisis se simplica gracias a un montn de mtodos que se pueden llamar desde el ujo del segmento ($this->parser->getStream()): getCurrent(): Obtiene el segmento actual del ujo. next(): Mueve al siguiente segmento en la secuencia, pero devuelve el antiguo. test($type), test($valor) o test($type, $valor): Determina si el segmento actual es de un tipo o valor particular (o ambos). El valor puede ser una matriz de varios posibles valores. expect($type[, $valor[, $message]]): Si el segmento actual no es del tipo/valor dado lanza un error de sintaxis. De lo contrario, si el tipo y valor son correctos, devuelve el segmento y mueve el ujo al siguiente segmento. look(): Busca el siguiente segmento sin consumirlo. Las expresiones de anlisis se llevan a cabo llamando a parseExpression() como lo hicimos para la etiqueta set. Truco: Leer las clases TokenParser existentes es la mejor manera de aprender todos los detalles esenciales del proceso de anlisis.

4.4.3 Deniendo un nodo


La clase Project_Set_Node en s misma es bastante simple:
class Project_Set_Node extends Twig_Node { public function __construct($nombre, Twig_Node_Expression $valor, $lineno) { parent::__construct(array(value => $valor), array(name => $nombre), $lineno); } public function compile(Twig_Compiler $compilador) { $compilador ->addDebugInfo($this) ->write($contexto[\.$this->getAttribute(name).\] = ) ->subcompile($this->getNode(value)) ->raw(";\n") ; } }

El compilador implementa una interfaz uida y proporciona mtodos que ayudan a los desarrolladores a generar cdigo PHP hermoso y fcil de leer: subcompile(): Compila un nodo.

40

Captulo 4. Extendiendo Twig

Manual de Twig, Release 1.2.0

raw(): Escribe la cadena dada tal cual. write(): Escribe la cadena dada aadiendo sangra al principio de cada lnea. string(): Escribe una cadena entre comillas. repr(): Escribe una representacin PHP de un valor dado (consulta Twig_Node_For para un ejemplo real). addDebugInfo(): Agrega como comentario la lnea del archivo de plantilla original relacionado con el nodo actual. indent(): Aplica sangras el cdigo generado (consulta Twig_Node_Block para un ejemplo real). outdent(): Quita la sangra al cdigo generado (consulta Twig_Node_Block para un ejemplo de uso).

4.4. Etiquetas

41

Manual de Twig, Release 1.2.0

42

Captulo 4. Extendiendo Twig

CAPTULO 5

Creando una extensin Twig

La principal motivacin para escribir una extensin es mover el cdigo usado frecuentemente a una clase reutilizable como agregar apoyo para la internacionalizacin. Una extensin puede denir etiquetas, ltros, pruebas, operadores, variables globales, funciones y visitantes de nodo. La creacin de una extensin tambin hace una mejor separacin del cdigo que se ejecuta en tiempo de compilacin y el cdigo necesario en tiempo de ejecucin. Como tal, esto hace tu cdigo ms rpido. La mayora de las veces, es til crear una extensin para tu proyecto, para acoger todas las etiquetas y ltros especcos que deseas agregar a Twig. Nota: Antes de escribir tus propias extensiones, echa un vistazo al repositorio ocial de extensiones Twig: http://github.com/fabpot/Twig-extensions. Una extensin es una clase que implementa la siguiente interfaz:
interface Twig_ExtensionInterface { /** * Inicia el entorno en tiempo de ejecucin. * * Aqu es donde puedes cargar algn archivo que contenga funciones de filtro, por ejemplo. * * @param Twig_Environment $environment La instancia actual de Twig_Environment */ public function initRuntime(Twig_Environment $environment);

/** * Devuelve instancias del analizador de segmentos para aadir a la lista existente. * * @return array Una matriz de ejemplares de Twig_TokenParserInterface o Twig_TokenParserBrokerIn */ public function getTokenParsers(); /** * Devuelve ejemplares del visitante de nodos para aadirlos a la lista existente. * * @return array Una matriz de ejemplares de Twig_NodeVisitorInterface */ public function getNodeVisitors();

43

Manual de Twig, Release 1.2.0

/** * Devuelve una lista de filtros para aadirla a la lista existente. * * @return array Una matriz de filtros */ public function getFilters(); /** * Devuelve una lista de prueba para aadirla a la lista existente. * * @return array Un arreglo de pruebas */ public function getTests(); /** * Devuelve una lista de operadores para aadirla a la lista existente. * * @return array Una matriz de operadores */ public function getOperators(); /** * Devuelve una lista de funciones globales para aadirla a la lista existente. * * @return array Una matriz de funciones globales */ public function getGlobals(); /** * Devuelve el nombre de la extensin. * * @return string El nombre de la extensin */ public function getName(); }

Para mantener tu clase de extensin limpia y ordenada, puedes heredar de la clase Twig_Extension incorporada en lugar de implementar toda la interfaz. De esta forma, slo tienes que implementar el mtodo getName() como el que proporcionan las implementaciones vacas de Twig_Extension para todos los otros mtodos. El mtodo getName() debe devolver un identicador nico para tu extensin. Ahora, con esta informacin en mente, vamos a crear la extensin ms bsica posible:
class Project_Twig_Extension extends Twig_Extension { public function getName() { return project; } }

Nota: Por supuesto, esta extensin no hace nada por ahora. Vamos a personalizarla en las siguientes secciones. A Twig no le importa dnde guardas tu extensin en el sistema de archivos, puesto que todas las extensiones se deben registrar explcitamente para estar disponibles en tus plantillas. Puedes registrar una extensin con el mtodo addExtension() en tu objeto Environment principal: 44 Captulo 5. Creando una extensin Twig

Manual de Twig, Release 1.2.0

$twig = new Twig_Environment($cargador); $twig->addExtension(new Project_Twig_Extension());

Por supuesto, tienes que cargar primero el archivo de la extensin, ya sea utilizando require_once() o con un cargador automtico (consulta la seccin spl_autoload_register()). Truco: Las extensiones integradas son grandes ejemplos de cmo trabajan las extensiones.

5.1 Globales y funciones


Las variables y funciones globales se pueden registrar en una extensin a travs del mtodo getGlobals():
class Project_Twig_Extension extends Twig_Extension { public function getGlobals() { return array( text => new Text(), lipsum => new Twig_Function(new Text(), getLipsum), ); } // ... }

5.2 Filtros
Para agregar un ltro a una extensin, es necesario sustituir el mtodo getFilters(). Este mtodo debe devolver una matriz de ltros para aadir al entorno Twig:
class Project_Twig_Extension extends Twig_Extension { public function getFilters() { return array( rot13 => new Twig_Filter_Function(str_rot13), ); } // ... }

Como puedes ver en el cdigo anterior, el mtodo getFilters() devuelve una matriz donde las claves son el nombre de los ltros (rot13) y los valores de la denicin del ltro (new Twig_Filter_Function(str_rot13)). Como vimos en el captulo anterior, tambin puedes denir ltros como mtodos estticos en la clase de la extensin:
$twig->addFilter(rot13, new Twig_Filter_Function(Project_Twig_Extension::rot13Filter));

Tambin puedes utilizar Twig_Filter_Method en lugar de Twig_Filter_Function cuando denas un ltro que usa un mtodo:

5.1. Globales y funciones

45

Manual de Twig, Release 1.2.0

class Project_Twig_Extension extends Twig_Extension { public function getFilters() { return array( rot13 => new Twig_Filter_Method($this, rot13Filter), ); } public function rot13Filter($cadena) { return str_rot13($cadena); } // ... }

El primer argumento del constructor de Twig_Filter_Method siempre es $this, el objeto extensin actual. El segundo es el nombre del mtodo a llamar. Usar mtodos de ltro es una gran manera de empaquetar el ltro sin contaminar el espacio de nombres global. Esto tambin le da ms exibilidad al desarrollador a costa de una pequea sobrecarga.

5.2.1 Sustituyendo los ltros predeterminados


Si algunos ltros predeterminados del ncleo no se ajustan a tus necesidades, fcilmente puedes sustituirlos creando tu propia extensin del ncleo. Por supuesto, no es necesario copiar y pegar el cdigo del ncleo en toda tu extensin de Twig. En lugar de eso la puedes extender y sustituir los ltros que deseas reemplazando el mtodo getFilters():
class MiExtensionCore extends Twig_Extension_Core { public function getFilters() { return array_merge(parent::getFilters(), array( date => new Twig_Filter_Method($this, dateFilter), // ... )); } public function dateFilter($timestamp, $format = F j, Y H:i) { return ....twig_date_format_filter($timestamp, $format); } // ... }

Aqu, reemplazamos el ltro date con uno personalizado. Usar esta nueva extensin del ncleo es tan simple como registrar la extensin MiExtensionCore llamando al mtodo addExtension() en la instancia del entorno:
$twig = new Twig_Environment($cargador); $twig->addExtension(new MiExtensionCore());

Pero ya puedo escuchar a algunas personas preguntando cmo pueden hacer que la extensin del ncleo se cargue por omisin. Eso es cierto, pero el truco es que ambas extensiones comparten el mismo identicador nico (core denido en el mtodo getName()). Al registrar una extensin con el mismo nombre que una ya existente, realmente sustituyes la predeterminada, incluso si ya est registrada:

46

Captulo 5. Creando una extensin Twig

Manual de Twig, Release 1.2.0

$twig->addExtension(new Twig_Extension_Core()); $twig->addExtension(new MiExtensionCore());

5.3 Etiquetas
Puedes agregar una etiqueta en una extensin reemplazando el mtodo getTokenParsers(). Este mtodo debe devolver una matriz de etiquetas para aadir al entorno Twig:
class Project_Twig_Extension extends Twig_Extension { public function getTokenParsers() { return array(new Project_Set_TokenParser()); } // ... }

En el cdigo anterior, hemos aadido una sola etiqueta nueva, denida por la clase Project_Set_TokenParser. La clase Project_Set_TokenParser es responsable de analizar la etiqueta y compilarla a PHP.

5.4 Operadores
El mtodo getOperators() te permite aadir nuevos operadores. Aqu tienes cmo aadir los operadores !, || y &&:

class Project_Twig_Extension extends Twig_Extension { public function getOperators() { return array( array( ! => array(precedence => 50, class => Twig_Node_Expression_Unary_Not), ), array( || => array(precedence => 10, class => Twig_Node_Expression_Binary_Or, assoc && => array(precedence => 15, class => Twig_Node_Expression_Binary_And, asso ), ); } // ... }

5.5 Pruebas
El mptodo getTests() te permite aadir funciones de prueba:
class Project_Twig_Extension extends Twig_Extension { public function getTests() {

5.3. Etiquetas

47

Manual de Twig, Release 1.2.0

return array( even => new Twig_Test_Function(twig_test_even), ); } // ... }

48

Captulo 5. Creando una extensin Twig

CAPTULO 6

Mejorando Twig

Twig es muy extensible y lo puedes mejorar fcilmente. Ten en cuenta que probablemente deberas tratar de crear una extensin antes de sumergirte en el ncleo, puesto que la mayora de caractersticas y mejoras se pueden hacer con extensiones. Este captulo tambin es til para personas que quieren entender cmo funciona Twig debajo del cap.

6.1 Cmo funciona Twig?


La reproduccin de una plantilla Twig se puede resumir en cuatro pasos fundamentales: Cargar la plantilla: Si la plantilla ya est compilada, crgala y ve al paso evaluacin, de lo contrario: En primer lugar, el analizador lxico acorta el cdigo fuente de la plantilla en pequeas piezas para facilitar su procesamiento; A continuacin, el analizador convierte el ujo del segmento en un rbol de nodos signicativo (el rbol de sintaxis abstracta); Eventualmente, el compilador transforma el rbol de sintaxis abstracta en cdigo PHP; Evaluar la plantilla: Bsicamente signica llamar al mtodo display() de la plantilla compilada adjuntando el contexto.

6.2 El analizador lxico


El objetivo del analizador lxico de Twig es dividir el cdigo fuente en un ujo de segmentos (donde cada segmento es de la clase token, y el ujo es una instancia de Twig_TokenStream). El analizador lxico predeterminado reconoce nueve diferentes tipos de segmentos: Twig_Token::TEXT_TYPE Twig_Token::BLOCK_START_TYPE Twig_Token::VAR_START_TYPE Twig_Token::BLOCK_END_TYPE Twig_Token::VAR_END_TYPE Twig_Token::NAME_TYPE

49

Manual de Twig, Release 1.2.0

Twig_Token::NUMBER_TYPE Twig_Token::STRING_TYPE Twig_Token::OPERATOR_TYPE Twig_Token::EOF_TYPE Puedes convertir manualmente un cdigo fuente en un ujo de segmentos llamando al mtodo tokenize() de un entorno:
$flujo = $twig->tokenize($fuente, $identificador);

Dado que el ujo tiene un mtodo __toString(), puedes tener una representacin textual del mismo haciendo eco del objeto:
echo $flujo."\n";

Aqu est la salida para la plantilla Hola {{ nombre }}:


TEXT_TYPE(Hola ) VAR_START_TYPE() NAME_TYPE(nombre) VAR_END_TYPE() EOF_TYPE()

Puedes cambiar el analizador lxico predeterminado que usa Twig (Twig_Lexer) llamando al mtodo setLexer():
$twig->setLexer($lexer);

Las clases Lexer deben implementar a Twig_LexerInterface:


interface Twig_LexerInterface { /** * Segmenta un cdigo fuente. * El cdigo fuente * @param string $codigo * @param string $nombrearchivo Un identificador nico para el cdigo fuente * * @return Twig_TokenStream Una instancia del flujo de segmentos */ function tokenize($codigo, $nombrearchivo = n/a); }

6.3 El analizador sintctico


El analizador convierte el ujo de segmentos en un ASA (rbol de sintaxis abstracta), o un rbol de nodos (de clase Twig_Node_Module). La extensin del ncleo dene los nodos bsicos como: for, if, ... y la expresin nodos. Puedes convertir manualmente un ujo de segmentos en un nodo del rbol llamando al mtodo parse() de un entorno:
$nodos = $twig->parse($flujo);

Al hacer eco del objeto nodo te da una buena representacin del rbol:

50

Captulo 6. Mejorando Twig

Manual de Twig, Release 1.2.0

echo $nodos."\n";

Aqu est la salida para la plantilla Hola {{ nombre }}:


Twig_Node_Module( Twig_Node_Text(Hola ) Twig_Node_Print( Twig_Node_Expression_Name(nombre) ) )

El analizador predeterminado (Twig_TokenParser) tambin se puede cambiar mediante una llamada al mtodo setParser():
$twig->setParser($analizador);

Todos los analizadores de Twig deben implementar a Twig_ParserInterface:


interface Twig_ParserInterface { /** * Convierte un flujo de segmentos en un rbol de nodos. * * @param Twig_TokenStream $flujo Una instancia del flujo de segmentos * * @return Twig_Node_Module Un rbol de nodos */ function parser(Twig_TokenStream $codigo); }

6.4 El compilador
El ltimo paso lo lleva a cabo el compilador. Este necesita un rbol de nodos como entrada y genera cdigo PHP que se puede emplear para ejecutar las plantillas en tiempo de ejecucin. El compilador predeterminado genera las clases PHP para facilitar la implementacin de la herencia de plantillas. Puedes llamar al compilador manualmente con el mtodo compile() de un entorno:
$php = $twig->compile($nodos);

El mtodo compile() devuelve el cdigo fuente PHP que representa el nodo. La plantilla generada por un patrn Hola {{ nombre }} es la siguiente:
/* Hola {{ nombre }} */ class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template { public function display($contexto) { $this->env->initRuntime(); // lnea 1 echo "Hola "; echo (isset($contexto[nombre]) ? $contexto[nombre] : null); } }

6.4. El compilador

51

Manual de Twig, Release 1.2.0

En cuanto a los analizadores lxico y sintctico, el compilador predeterminado (Twig_Compiler) se puede cambiar mediante una llamada al mtodo setCompiler():
$twig->setCompiler($compilador);

Todos los compiladores de Twig deben implementar a Twig_CompilerInterface:


interface Twig_CompilerInterface { /** * Compila un nodo. * * @param Twig_Node $nodo El nodo a compilar * * @return Twig_Compiler La instancia del compilador actual */ function compile(Twig_Node $nodo); /** * Obtiene el cdigo *PHP* actual despus de la compilacin. * * @return string El cdigo PHP */ function getSource(); }

52

Captulo 6. Mejorando Twig

CAPTULO 7

Recetas

7.1 Haciendo un diseo condicional


Trabajar con Ajax signica que el mismo contenido a veces se muestra tal cual, y a veces se decora con un diseo. Dado que el nombre del diseo de las plantillas Twig puede ser cualquier expresin vlida, puedes pasar una variable que evale a true cuando se hace la peticin a travs de Ajax y elegir el diseo en consecuencia:
{% extends request.ajax ? "base_ajax.html" : "base.html" %} {% block contenido %} Este es el contenido a mostrar. {% endblock %}

7.2 Haciendo una inclusin dinmica


Cuando incluyes una plantilla, su nombre no tiene por qu ser una cadena. Por ejemplo, el nombre puede depender del valor de una variable:
{% include var ~ _foo.html %}

Si var evala como index, se reproducir la plantilla index_foo.html. De hecho, el nombre de la plantilla puede ser cualquier expresin vlida, como la siguiente:
{% include var|default(index) ~ _foo.html %}

7.3 Sustituyendo una plantilla que adems se extiende a s misma


Puedes personalizar una plantilla de dos formas diferentes: Herencia: Una plantilla extiende a una plantilla padre y sustituye algunos bloques; Sustitucin: Si utilizas el cargador del sistema de archivos, Twig carga la primera plantilla si se encuentra en una lista de directorios congurados, una plantilla que se encuentra en un directorio sustituye a otra de un directorio ms en la lista.

53

Manual de Twig, Release 1.2.0

Pero, cmo se combinan las dos cosas?: sustituir una plantilla que tambin se extiende a s misma (tambin conocida como una plantilla en un directorio ms en la lista) Digamos que tus plantillas se cargan tanto .../plantillas/default, en este orden. .../plantillas/default es la siguiente:
{# pagina.twig #} {% extends "base.twig" %} {% block contenido %} {% endblock %}

desde .../plantillas/misitio como La plantilla pagina.twig almacenada

de en

Puedes sustituir esta plantilla poniendo un archivo con el mismo nombre en .../plantillas/misitio. Y si deseas ampliar la plantilla original, podras tener la tentacin de escribir lo siguiente:
{# pagina.twig in .../plantillas/misitio #} {% extends "pagina.twig" %} {# desde .../plantillas/default #}

Por supuesto, esto no funcionar debido a que Twig siempre carga la plantilla desde .../plantillas/misitio. Resulta que es posible conseguir que esto funcione, aadiendo el directorio adecuado al nal de tus directorios de plantilla, el cual es el padre de todos los otros directorios: .../plantillas en nuestro caso. Esto tiene el efecto de hacer que cada archivo de plantilla dentro de nuestro sistema sea direccionable unvocamente. La mayora de las veces utilizars rutas normales, pero en el caso especial de querer extender una plantilla con una versin que se redene a s misma podemos referirnos a la ruta completa del padre, sin ambigedades, en la etiqueta extends de la plantilla:
{# pagina.twig en .../plantillas/misitio #} {% extends "default/pagina.twig" %} {# desde .../plantillas #}

Nota: Esta receta est inspirada en http://code.djangoproject.com/wiki/ExtendingTemplates

la

siguiente

pgina

del

wiki

de

Django:

7.4 Sintaxis personalizada


Twig te permite personalizar alguna sintaxis de los delimitadores de bloque. No se recomienda usar esta caracterstica puesto que las plantillas sern vinculadas con tu sintaxis personalizada. Sin embargo, para proyectos especcos, puede tener sentido cambiar los valores predeterminados. Para cambiar los delimitadores de bloque, necesitas crear tu propio objeto lexer:
$twig = new Twig_Environment(); $lexer = new Twig_Lexer($twig, array( tag_comment => array({#, #}), tag_block => array({ %, %}), tag_variable => array({{, }}), )); $twig->setLexer($lexer);

stos son algunos ejemplos de conguracin que simulan la sintaxis de algunos otros motores de plantilla:
// sintaxis erb de Ruby $lexer = new Twig_Lexer($twig, array( tag_comment => array(< %#, %>), tag_block => array(< %, %>),

54

Captulo 7. Recetas

Manual de Twig, Release 1.2.0

tag_variable => array(< %=, %>), )); // sintaxis de comentarios SGML $lexer = new Twig_Lexer($twig, array( tag_comment => array(<!--#, -->), tag_block => array(<!--, -->), tag_variable => array(${, }), )); // como Smarty $lexer = new Twig_Lexer($twig, array( tag_comment => array({*, *}), tag_block => array({, }), tag_variable => array({$, }), ));

7.5 Usando propiedades dinmicas de los objetos


Cuando Twig encuentra una variable como articulo.titulo, trata de encontrar una propiedad pblica titulo en el objeto articulo. Tambin funciona si la propiedad no existe, pero ms bien est denida de forma dinmica gracias a la magia del mtodo __get(), slo tienes que implementar tambin el mtodo mgico __isset(), como muestra el siguiente fragmento de cdigo:
class Articulo { public function __get($nombre) { if (titulo == $nombre) { return El ttulo; } // lanza algn tipo de error } public function __isset($nombre) { if (titulo == $nombre) { return true; } return false; } }

7.6 Accediendo al contexto del padre en bucles anidados


A veces, cuando utilizas bucles anidados, necesitas acceder al contexto del padre. El contexto del padre siempre es accesible a travs de la variable loop.parent. Por ejemplo, si tienes los siguientes datos de plantilla:

7.5. Usando propiedades dinmicas de los objetos

55

Manual de Twig, Release 1.2.0

$datos = array( temas => array( tema1 => array(Mensaje 1 del tema 1, Mensaje 2 del tema 1), tema2 => array(Mensaje 1 del tema 2, Mensaje 2 del tema 2), ), );

Y la siguiente plantilla para mostrar todos los mensajes en todos los temas:
{% for tema, mensajes in temas %} * {{ loop.index }}: {{ tema }} {% for mensaje in mensajes %} - {{ loop.parent.loop.index }}.{{ loop.index }}: {{ mensaje }} {% endfor %} {% endfor %}

Reproducir algo similar a:


* 1: tema1 - 1.1: El - 1.2: El * 2: tema2 - 2.1: El - 2.2: El mensaje 1 del tema 1 mensaje 2 del tema 1 mensaje 1 del tema 2 mensaje 2 del tema 2

En el bucle interno, utilizamos la variable loop.parent para acceder al contexto externo. As, el ndice del tema actual denido en el exterior del bucle es accesible a travs de la variable loop.parent.loop.index.

7.7 Deniendo al vuelo funciones indenidas y ltros


Cuando una funcin (o un ltro) no est denido, de manera predeterminada Twig lanza una excepcin Twig_Error_Syntax. Sin embargo, tambin puede invocar una retrollamada (cualquier PHP vlido que se pueda ejecutar) la cual debe devolver una funcin (o un ltro). Para ltros, registra las retrollamadas con registerUndefinedFilterCallback(). Para funciones, usa registerUndefinedFunctionCallback():
// Autoregistra todas las funciones nativas de PHP como funciones Twig // no intentes esto en casa, ya que no es seguro en absoluto! $twig->registerUndefinedFunctionCallback(function ($nombre) { if (function_exists($nombre)) { return new Twig_Function_Function($nombre); } return false; });

Si el ejecutable no es capaz de devolver una funcin vlida (o ltro), deber devolver false. Si registras ms de una retrollamada, Twig la llamar a su vez hasta que una no devuelva false. Truco: Debido a que la resolucin de funciones y ltros se realiza durante la compilacin, no hay ninguna sobrecarga cuando registras estas retrollamadas.

56

Captulo 7. Recetas

Manual de Twig, Release 1.2.0

7.8 Validando la sintaxis de la plantilla


Cuando el cdigo de plantilla lo proporciona un tercero (a travs de una interfaz web, por ejemplo), podra ser interesante validar la sintaxis de la plantilla antes de guardarla. Si almacenas el cdigo de la plantilla en una variable $plantilla, aqu tienes cmo lo puedes hacer:
try { $twig->parse($twig->tokenize($plantilla)); // la $plantilla es vlida } catch (Twig_Error_Syntax $e) { // $plantilla contiene uno o ms errores de sintaxis }

7.8. Validando la sintaxis de la plantilla

57

Das könnte Ihnen auch gefallen