Twig, el nuevo motor de plantillas de Drupal 8

Preview:

DESCRIPTION

 

Citation preview

TWIGEL NUEVO MOTOR DEPLANTILLAS PARA

DRUPAL 8JAVIER EGUILUZDRUPALCAMPSPAIN 26 OCTUBRE 2013

Licencia de esta presentación

creativecommons.org/licenses/by-nc-sa/3.0/es

Muchas gracias a los patrocinadores

Asociación Española de Drupal

ME PRESENTO

Formador especializado en

nuevas tecnologías

Javier Eguiluz

Diseño y programación web Comunidad sobre el framework Symfony

Programador entusiasta del framework Symfony

+

también explica Twig

empieza desde cero

actualizaciones gratuitas incluidas

soporta todas las versiones de Symfony2

AGENDA

PRIMERA PARTE

APRENDIENDO TWIGSEGUNDA PARTE

TWIG AVANZADOTERCERA PARTE

APLICANDO TWIG

PRIMERA PARTE

APRENDIENDO TWIG

• Twig es un motor y lenguaje de plantillas (como PHP, Smarty, Moustache, etc.)

• Twig es el sistema de plantillas utilizado por Drupal 8.

¿Qué es Twig?

Integrando Twig desde julio 2012

TWIG ENDRUPAL 8

Nueva forma de pensar$variables['table'] = theme('table', array( 'header' => $header, 'rows' => $rows));

$variables['table'] = array( '#theme' => 'table', '#header' => $header, '#rows' => $rows,);

D7

D8

SINTAXIS

core/modules/node/templates/node.html.twig

<div {{ attributes }}> {# hide the comments to render them later #}

{% hide(content.comments) %} {{ content }}</div>

core/modules/node/templates/node.html.twig

<div {{ attributes }}> {# hide the comments to render them later #}

{% hide(content.comments) %} {{ content }}</div>

{{ ... }} mostrar información

core/modules/node/templates/node.html.twig

<div {{ attributes }}> {# hide the comments to render them later #}

{% hide(content.comments) %} {{ content }}</div>

{# ... #} añadir comentarios

core/modules/node/templates/node.html.twig

<div {{ attributes }}> {# hide the comments to render them later #}

{% hide(content.comments) %} {{ content }}</div>

{% ... %} ejecutarcódigo

Sintaxis de Twig

{{ mostrar información }}

{% ejecutar código %}

{# añadir comentario #}

MOSTRANDO INFORMACIÓN

Variables simples

{{ titulo_articulo }}{{ nombre_usuario }}{{ precio }}

Variables de cada plantilla{# core/modules/node/templates/node.html.twig #}{# Default theme implementation to display a node. Available variables: - node: Full node entity. - id: The node ID - bundle: The type of the node, for example, "page" or "article". - authorid: The user ID of the node author. - createdtime: Formatted creation date. ... #}<article id="node-{{ node.id }}" class="{{ attributes.class }} clearfix"{{ attributes }}>

{{ title_prefix }} {% if not page %} <h2{{ title_attributes }}> <a href="{{ node_url }}" rel="bookmark">{{ label }}</a> </h2> {% endif %} {{ title_suffix }}

{% if display_submitted %} <footer> {{ user_picture }}

las plantillas de Drupal 8 listan todas sus variables

Variables complejas

{{ articulo.titulo }}{{ usuario.nombre }}{{ producto.precio }}

{{ usuario.nombre }}

1. $usuario['nombre']2. $usuario->nombre3. $usuario->nombre()4. $usuario->getNombre()5. $usuario->isNombre()6. null

Concatenando variables

{{ "El producto " ~ producto.titulo ~ " cuesta " ~ producto.precio ~ " euros" }}

El producto XXX cuesta NNN euros

concatena variables

Interpolando variables

{{ "El producto #{producto.titulo} cuesta #{producto.precio} euros" }}

El producto XXX cuesta NNN euros

interpola variables

CREANDO VARIABLES

Creando una nueva variable

{% set numero = 3 %}El número elegido es {{ numero }}

{% set nombreCompleto = nombre ~ ' ' ~ apellidos %}

Tipos de variables

{% set entero = 3 %}

{% set decimal = 3.14 %}

{% set cadena = "..." %}

{% set booleano = false %}

{% set array = [1, 2, 3, 4, 5] %}

{% set hash = {'a': 1, 'b': 2} %}

Ejemplo de variable compleja{# core/modules/node/templates/node.html.twig #}node = { 'id': 1, 'bundle': 'page', 'authorid': 23, 'promoted': false, 'sticky': false, 'published': true, 'comment': 2, 'comment_count': 0}

truco

Trozos de código como variables

{% set navegacion %} <a href="...">Anterior</a> ... ... <a href="...">Siguiente</a>{% endset %}

Trozos de código como variables

{% set navegacion %} <a href="...">Anterior</a> ... ... <a href="...">Siguiente</a>{% endset %}

{{ navegacion }}

{{ navegacion }}

FILTROS

Los filtros de Twig

Modifican la información antes de mostrarla por pantalla.

Sintaxis

{{ variable|filtro }}

Ejemplo de filtros para texto

{{ "..."|lower }}

{{ "..."|upper }}

{{ "..."|title }}

{{ "..."|capitalize }}

lorem ipsum

LOREM IPSUM

Lorem Ipsum

Lorem ipsum

lorEm iPsUm

Los filtros que define Twigabsbatchcapitalizeconvert_encodingdatedate_modifydefaultescapefirstformatjoin

json_encodekeyslastlengthlowermergenl2brnumber_formatrawreplacereverse

slicesortsplitstriptagstitletrimupperurl_encode

Filtros con argumentos

{{ descripcion|striptags }}{{ descripcion|striptags('<p>') }}

{{ precio|number_format }}{{ precio|number_format(3) }}{{ precio|number_format(3, '.') }}

Tienes {{ amigos|length }} amigos

Tu nombre tiene {{ nombre|length }} letras

Los filtros se adaptan

Tienes {{ amigos|length }} amigos

Tu nombre tiene {{ nombre|length }} letras

Los filtros se adaptan

count()

strlen()

{{ titulo|striptags|title }}

{{ direcciones|first|trim|capitalize }}

Encadenando filtros

truco

<p>{{ nombre|striptags|trim }}</p>

<p>{{ apellidos|striptags|trim }}</p>

<p>{{ biografia|striptags|trim }}</p>

Aplicando filtros a varios elementos

{% filter striptags|trim %}

<p>{{ nombre }}</p> <p>{{ apellidos }}</p> <p>{{ biografia }}</p>

{% endfilter %}

Aplicando filtros a varios elementos

LOS FILTROS DE DRUPAL 8

El filtro para traducir contenidos

{{ '...'|t }}

Traduciendo contenidos fijos{# core/modules/aggregator/templates/aggregator-item.html.twig #}

{{ 'Categories'|t }}: {{ categories|join(', ') }}

{# core/modules/comment/templates/comment-wrapper.html.twig #}

<h3>{{ 'Comments are displayed in a list.'|t }}</h3>

<h2 class="title">{{ 'Comments'|t }}</h2>

<h2 class="title comment-form">{{ 'Add comment'|t }}</h2>

Traduciendo contenidos variables

'More posts about Drupal 8''More posts about Twig''More posts about Symfony'

Traduciendo contenidos variables

'More posts about Drupal 8''More posts about Twig''More posts about Symfony'

traducir la parte fija

considerarlo una variable

Traduciendo contenidos variables{# core/modules/aggregator/templates/aggregator-summary-items.html.twig #}

<a href="{{ source_url }}">

{{ 'More posts about %title'|t({ '%title': title }) }}</a>

{# core/modules/locale/templates/locale-translation-last-check.html.twig #}

{{ 'Last checked: @time ago'|t({'@time': time}) }}

Traduciendo contenidos variables{# core/modules/aggregator/templates/aggregator-summary-items.html.twig #}

<a href="{{ source_url }}">

{{ 'More posts about %title'|t({ '%title': title }) }}</a>

{# core/modules/locale/templates/locale-translation-last-check.html.twig #}

{{ 'Last checked: @time ago'|t({'@time': time}) }}

FUNCIONES

Las funciones de Twig

Generan información para mostrarla por pantalla.

Sintaxis

{{ funcion() }}{{ funcion('...') }}{{ funcion('...', '...') }}

Ejemplo de función de Twig

{{ random() }}

{{ random(10) }}

{{ random("abcde") }}

{{ random([1, 2, 3]) }}

ETIQUETAS

Las etiquetas de Twig

Ejecutan operaciones complejas como la herencia de plantillas y controlan la ejecución de la plantilla.

Las etiquetas que define Twig

autoescapeblockdoembedextendsfilterflush

forfromifimportincludemacrosandbox

setspacelessuseverbatim

Las etiquetas de control de flujo

if ... elseswitchreturnbreakcontinue

forforeachwhiledo ... whilegoto

if ... else for

PHP

TWIG

LA ETIQUETAIF

La etiqueta IF básica{# core/modules/block/templates/block.html.twig #}<div> {{ title_prefix }}

{% if label %} <h2 {{ attributes }}>{{ label }}</h2>

{% endif %} {{ title_suffix }}</div>

La etiqueta IF básica{# core/modules/block/templates/block.html.twig #}<div> {{ title_prefix }}

{% if label %} <h2 {{ attributes }}>{{ label }}</h2>

{% endif %} {{ title_suffix }}</div>

✔ Existe la variable✔ No es null✔ No es cadena vacía

La etiqueta IF

{% if variable %}

...

{% endif %}

Tomando decisiones{# core/modules/system/templates/page.html.twig #}

{% if title %} <b><a href="...">{{ site_name }}</a></b>

{% else %} <h1 class="site-name"> <a href="...">{{ site_name }}</a> </h1>

{% endif %}

La etiqueta IF

{% if variable %}

...

{% else %}

...

{% endif %}

Tomando varias decisiones{# core/modules/locale/templates/locale-translation-update-info.html.twig #}

{% if modules %} <span>{{ 'Updates for: modules' }}</span>

{% elseif missing_updates_status %} <span>{{ missing_updates_status }}</span>

{% endif %}

La etiqueta IF

{% if variable %} ...{% elseif variable %} ...{% else %} ...{% endif %}

Condiciones múltiples{# core/modules/book/templates/book-navigation.html.twig #}

{% if tree or has_links %} <nav class="book-navigation"> {{ tree }}

{% if has_links %} ... {% endif %} </nav>

{% endif %}

Condiciones múltiples{# core/modules/book/templates/book-navigation.html.twig #}

{% if tree or has_links %} <nav class="book-navigation"> {{ tree }}

{% if has_links %} ... {% endif %} </nav>

{% endif %}

Operadores lógicos

andornot

b-andb-orb-xor

Condiciones múltiples

{% if not label_hidden %}

{% if not label_hidden or user.is_admin %}

{% if label_hidden and not user.is_admin %}

{% if (label_hidden or user.is_admin) and node.is_published %}

Comparaciones{# core/modules/views/templates/views-view-grid.html.twig #}

{% if options.alignment == 'horizontal' %}

{# core/modules/views/templates/views-view-list.html.twig #}

{% if list.type == 'ul' %}

Comparaciones{# core/modules/views/templates/views-view-grid.html.twig #}

{% if options.alignment == 'horizontal' %}

{# core/modules/views/templates/views-view-list.html.twig #}

{% if list.type == 'ul' %}Operadores de comparación

==!=<

>>=<=

=== starts with ends withmatches

FECHAS

Intentando mostrar una fecha

{{ usuario.fechaNacimiento }}

ERRORAn exception has been thrown during the rendering of a template:

"Catchable Fatal Error: Object of class DateTime could not be converted to string in [...] line XX"

Intentando mostrar una fecha

{{ usuario.fechaNacimiento }}

variable de tipoDateTime

Mostrando fechas

{{ usuario.fechaNacimiento|date }}

Mostrando fechas

{{ usuario.fechaNacimiento|date }}

{{ ...|date('d/m/Y') }}{{ ...|date('d/m/Y H:i:s') }}

Mostrando fechas

{{ usuario.fechaNacimiento|date }}

{{ ...|date('d/m/Y') }}{{ ...|date('d/m/Y H:i:s') }}{{ ...|date('d \\d\\e F \\d\\e Y') }}

Mostrando fechas

{{ usuario.fechaNacimiento|date }}

{{ ...|date('d/m/Y') }}{{ ...|date('d/m/Y H:i:s') }}{{ ...|date('d \\d\\e F \\d\\e Y') }}

26 de Octubre de 2013

truco

Creando fechas

{{ 'now'|date }}{{ 'today'|date }}{{ 'next Monday'|date }}{{ '+ 10 minutes'|date }}

Creando fechas

{{ 'now'|date }}{{ 'today'|date }}{{ 'next Monday'|date }}{{ '+ 10 minutes'|date }}

strtotime()

Creando fechas

<footer> © {{ 'now'|date('Y') }} ACME.org</footer>

Modificando fechas

{{ usuario.fechaNacimiento |date_modify('-9 months')|date }}

{{ usuario.fechaNacimiento |date_modify('+18 years')|date }}

Modificando fechas

<p> Activa tu cuenta antes del {{ usuario.fechaRegistro |date_modify('+1 week')|date }}</p>

SEGUNDA PARTE

TWIGAVANZADO

BUCLES Y COLECCIONES

Colecciones

Array (asociativo o numérico) o un objeto que implemente la interfaz Traversable.

Secuencias

{{ 1..3 }} [1, 2, 3]{{ 5..2 }} [5, 4, 3, 2]{{ 'a'..'d' }} ['a', 'b', 'c', 'd']

Las migas de pan del foro{# core/modules/forum/lib/Drupal/forum/ForumBreadcrumbBuilder.php #}

function forumPostBreadcrumb($node) {

$vocabulary = $this->entityManager->...->load('...');

$breadcrumb[] = l(t('Home'), NULL);

$breadcrumb[] = l($vocabulary->label(), 'forum');

// ...

return $breadcrumb;}

Mostrando las migas de pan<nav class="breadcrumb" role="navigation"> <ol>

{% for item in breadcrumb %} <li>{{ item }}</li>

{% endfor %} </ol></nav>

Mostrando las migas de pan<nav class="breadcrumb" role="navigation"> <ol>

{% for item in breadcrumb %} <li>{{ item }}</li>

{% endfor %} </ol></nav>

Mostrando las migas de pan<nav class="breadcrumb" role="navigation"> <ol>

{% for item in breadcrumb %} <li>{{ item }}</li>

{% endfor %} </ol></nav>

El bucle FOR

{% for valor in coleccion %}

...

{% endfor %}

El listado de libros{# core/modules/book/book.module #}function template_preprocess_book_all_books_block(&$variables) { // Remove all non-renderable elements. $elements = $variables['book_menus']; $variables['book_menus'] = array(); foreach (element_children($elements) as $index) { $variables['book_menus'][$index] = $elements[$index]; }}

El listado de libros{# core/modules/book/book.module #}function template_preprocess_book_all_books_block(&$variables) { // Remove all non-renderable elements. $elements = $variables['book_menus']; $variables['book_menus'] = array(); foreach (element_children($elements) as $index) { $variables['book_menus'][$index] = $elements[$index]; }}

$book_menus[$index] = ...

Mostrando el listado de libros

{% for book_id, menu in book_menus %} <nav id="book-block-menu-{{ book_id }}"> {{ menu }} </nav>

{% endfor %}

El bucle FOR

{% for clave, valor in coleccion %}

...

{% endfor %}

Accediendo a las claves de la colección

{% for clave in coleccion|keys %}

...

{% endfor %}

truco

La variable especial LOOP

{% for ... in coleccion %} {{ loop.index }} {{ loop.index0 }} {{ loop.first }} {{ loop.last }} {{ loop.length }}

{% endfor %}

La variable especial LOOP

{% for ... in coleccion %} {{ loop.index }} {{ loop.index0 }} {{ loop.first }} {{ loop.last }} {{ loop.length }}

{% endfor %}

1, 2, 3, 4, 5, ...0, 1, 2, 3, 4, ...true, false, false, ......, false, false, true5

¿Y si no hay libros?

{% for book_id, menu in book_menus %} <nav id="book-block-menu-{{ book_id }}"> {{ menu }} </nav>

{% else %} <p>No se ha publicado todavía ningún libro.</p>

{% endfor %}

El bucle FOR

{% for valor in coleccion %}

...

{% else %}

...

{% endfor %}

Indentando los mensajes del foro<div class="indent"> <div class="indent"> <div class="indent"> <div class="indent"> Lorem ipsum dolor sit amet, consectetur adipisic

ingelit, sed do eiusmodtempor incididunt ut labore

et dolore magna aliqua.

</div> </div> </div></div>

forum.depth

Indentando los mensajes del foro<div class="indent"> <div class="indent"> <div class="indent"> <div class="indent"> Lorem ipsum dolor sit amet, consectetur adipisic

ingelit, sed do eiusmodtempor incididunt ut labore

et dolore magna aliqua.

</div> </div> </div></div>

forum.depth

sólo si depth es mayor que cero

Indentando los mensajes del foro

{% for i in 1..forum.depth if forum.depth > 0 %} <div class="indent">

{% endfor %}

El bucle FOR

{% for valor in coleccion if condicion %}

...

{% endfor %}

El bucle FOR completo

{% for clave, valor in coleccion if condicion %} ...

{% else %}

...

{% endfor %}

Los filtros para colecciones

{% for ... in coleccion|sort %}

{% for ... in coleccion|reverse %}

{% for ... in coleccion|merge(otra_coleccion) %}

{% for ... in coleccion|slice(1, 3) %}

ESCAPANDO INFORMACIÓN

Este código es peligroso

<p> <?php echo $descripcion; ?></p>

Código mal formado

<p> <div> Lorem ipsum ... y no cierro el div</p>

Código mal formado

<p> <div> Lorem ipsum ... y no cierro el div</p>

esto destroza tu página

La solución PHP

<p><?php echo htmlspecialchars( $descripcion, ENT_QUOTES, 'UTF-8') ?></p>

La solución Twig

<p> {{ descripcion }}</p>

Twig escapa todo por defecto

<strong>Lorem ipsum</strong> dolor sit <em>amet</em>

{{ descripcion }}

&lt;strong&gt;Lorem ipsum&lt;/strong&gt; dolor sit &lt;em&gt;amet&lt;/em&gt;

<h1>{{ titulo }}</h1><h1><?php echo $titulo; ?></h1>

La gran diferencia entre Twig y PHP

SEGUROPOR DEFECTO

INSEGUROPOR DEFECTO

PHPTWIG

El filtro raw

{{ descripcion|raw }}

<strong>Lorem ipsum</strong> dolor sit <em>amet</em>

El filtro escape

{{ descripcion|e }}

&lt;strong&gt;Lorem ipsum&lt;/strong&gt; dolor sit &lt;em&gt;amet&lt;/em&gt;

Diferentes estrategias de escape

{{ descripcion|e('html') }}&lt;strong&gt;Lorem ipsum&lt;/strong&gt; dolor sit &lt;em&gt;amet&lt;/em&gt;

{{ descripcion|e('js') }}\x3Cstrong\x3ELorem\x20ipsum\x3C\x2Fstrong\x3E\x20dolor\x20sit\x20\x3Cem\x3Eamet\x3C\x2Fem\x3E

BATCH

Segmentando listas

1 2 3

4 5 6

7 8 9

Utilizando bucles normales

<table>

{% for i in 1..9 %} <td>{{ i }}</td>

{% endfor %}</table>

<table>

{% for i in 1..9 %}

{% if 0 == i % 3 %}<tr>{% endif %} <td>{{ i }}</td>

{% if 0 == i % 3 %}</tr>{% endif %}

{% endfor %}</table>

Utilizando bucles normales

El filtro batch<table>

{% for fila in 1..9|batch(3) %} <tr>

{% for columna in fila %} <td> {{ columna }} </td>

{% endfor %} </tr>

{% endfor %}</table>

El filtro batch<table>

{% for fila in 1..9|batch(3) %} <tr>

{% for columna in fila %} <td> {{ columna }} </td>

{% endfor %} </tr>

{% endfor %}</table>

saca los elementos de tres en tres

Rellenando los huecos<table>

{% for fila in 1..7|batch(3, '-') %} <tr> {% for columna in fila %} <td> {{ columna }} </td> {% endfor %} </tr>

{% endfor %}</table>

Rellenando los huecos<table>

{% for fila in 1..7|batch(3, '-') %} <tr> {% for columna in fila %} <td> {{ columna }} </td> {% endfor %} </tr>

{% endfor %}</table>

1 2 3

4 5 6

7 - -

DEPURACIÓN

DEPURACIÓN

EN DESARROLLOTODO ESTO PODRÍA CAMBIAR EN LA VERSIÓN ESTABLE DE DRUPAL 8!

Mostrar el contenido de variables

{{ dump(variable) }}

{{ dump(variable1, variable2) }}

{{ dump() }}

Mostrar el contenido de variables

{{ dump(variable) }}

{{ dump(variable1, variable2) }}

{{ dump() }} muestra TODAS las variables

Activar la función dump()

// sites/default/settings.php$settings['twig_debug'] = true;

Activar la función dump()

// sites/default/settings.php$settings['twig_debug'] = true;

twig_debug = false twig_debug = true

Activar la función dump()

// sites/default/settings.php$settings['twig_debug'] = true;

twig_debug = false twig_debug = true

<!-- THEME DEBUG --><!-- CALL: theme('html') --><!-- FILE NAME SUGGESTIONS: [o] html--node.html.twig [o] html--node--.html.twig [o] html--node--1.html.twig [x] html.html.twig --><!-- BEGIN OUTPUT from 'core/modules/system/templates/html.html.twig' --><!DOCTYPE html><html ...

Mejorando la depuración• dump( ) es muy útil, pero no deja de

ser un simple var_dump( ).

• Resulta muy difícil depurar variables complejas.

• Drupal 8 podría integrar el proyecto LadyBug.

Raúl Fraile

github.com/raulfraile/Ladybug

LadyBugDepurando aplicaciones PHP como un profesional.

Depurando con LadyBug$result = mysql_query('SELECT * FROM user', $conn);ladybug_dump($result);

Depurando con LadyBug$var = new Foo();ladybug_dump($var);

FRAGMENTOS DE PLANTILLAS

Plantillas con fragmentos repetidos

Plantillas con fragmentos repetidos

Fragmento de código repetido{# anuncio.twig #}<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><ins class="adsbygoogle" style="..." data-ad-client="..." data-ad-slot="..."></ins><script> (adsbygoogle = window.adsbygoogle || []).push({});</script>

Incluyendo un fragmento

...

{{ include('anuncio.twig') }}

...

Fragmento de código repetido{# anuncio.twig #}<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><ins class="adsbygoogle"

style="{{ ad.style }}"

data-ad-client="{{ ad.client }}"

data-ad-slot="{{ ad.slot }}"></ins>

<script> (adsbygoogle = window.adsbygoogle || []).push({});</script>

Incluyendo un fragmento con variables

...

{{ include('anuncio.twig', { ... }) }}

...

Incluyendo un fragmento con variables

...

{{ include('anuncio.twig', { ad: { 'style': '...', 'client': '...', 'slot': '...'}}) }}

...

Fragmentos sin variables

{{ include( 'anuncio.twig', with_context = false) }}

{{ include( 'anuncio.twig', { ... }, with_context = false) }}

Plantilla con muchos fragmentos

Plantilla con muchos fragmentos

include

HERENCIA DE PLANTILLAS

plantilla padre

plantilla padre igual para todas

las páginas

plantilla padre

huecos

igual para todas las páginas

plantillas hija

Herencia de plantillas

plantilla padre

plantillas hija

Herencia de plantillas

plantilla padre

en Twig se llaman bloques

Cómo funciona la herencia en Twig• Cada plantilla puede definir tantos

bloques como quiera.

• La herencia permite, pero no obliga, a rellenar los huecos.

• La plantilla padre puede rellenar sus huecos con contenido por defecto.

Creando la plantilla padre.twig<header> ... </header>

<div class="row"> <div class="span3"> HUECO 1 </div> <div class="span6"> HUECO 2 </div> <div class="span3"> ... </div></div>

<footer> ... </footer>

Creando la plantilla padre.twig<header> ... </header>

<div class="row"> <div class="span3"> side </div> <div class="span6"> main </div> <div class="span3"> ... </div></div>

<footer> ... </footer>

Creando la plantilla padre.twig<header> ... </header>

<div class="row"> <div class="span3">

{% block side %} {% endblock %} </div> <div class="span6">

{% block main %} {% endblock %} </div> <div class="span3"> ... </div></div>

<footer> ... </footer>

Creando la plantilla padre.twig<header> ... </header>

<div class="row"> <div class="span3">

{% block side %} {% endblock %} </div> <div class="span6">

{% block main %} {% endblock %} </div> <div class="span3"> ... </div></div>

<footer> ... </footer>

Creando la plantilla padre.twig<header> ... </header>

<div class="row"> <div class="span3">

{% block side %} {% endblock %} </div> <div class="span6">

{% block main %} {% endblock %} </div> <div class="span3"> ... </div></div>

<footer> ... </footer>

los nombres NO llevan comillas

Creando la plantilla hija.twig

{% extends 'padre.twig' %}

Creando la plantilla hija.twig

{% extends 'padre.twig' %}

{% block main %} ...{% endblock %}

{% block side %} ...{% endblock %}

plantilla hija

C D

plantilla padre

A B

plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

C D

plantilla padre

A B

plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

C D

{% extends 'padre.twig' %}{% block uno %} C {% endblock %}{% block dos %} D{% endblock %}

plantilla padre

A B

plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

A D

plantilla padre

A B

plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

A D

{% extends 'padre.twig' %}{% block dos %} D{% endblock %}

plantilla padre

A B

plantilla padre plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

A BA

DC

plantilla padre plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

A BA

D

{% extends 'padre.twig' %}{% block uno %} {{ parent() }} C {% endblock %}{% block dos %} D{% endblock %}

C

plantilla padre plantilla hija

<div>{% block uno %} A {% endblock %}</div>

<div>{% block dos %} B{% endblock %}</div>

A BA

D

{% extends 'padre.twig' %}{% block uno %} {{ parent() }} C {% endblock %}{% block dos %} D{% endblock %}

C

RENDIMIENTO

esta es la parte más lenta de Twig

Instalando la extensión de Twig

$ pear channel-discover pear.twig-project.org

$ pear install twig/CTwig

; php.iniextension=twig.so

Instalando la extensión de Twig

+15%

SIN extensión CON extensión

TERCERA PARTE

APLICANDO TWIG

DISEÑANDO SITIOS COMPLEJOS

Jerarquía de plantillas

layout.twig

pagina1.twig

pagina2.twig+

layout.twig

seccion1.twig

seccion2.twig+pagina1.twig

pagina2.twig+

Plantilla layout.twig<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>{% block title %}Lorem ipsum dolor.{% endblock %}</title> {% if block('description') != '' %} <meta name="description" content="{% block description %}{% endblock %}"> {% endif %} <link href="..." rel="stylesheet" type="text/css"> {% block head_css %}{% endblock %} {% block head_javascript %}{% endblock %} </head> ...

Plantilla layout.twig<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>{% block title %}Lorem ipsum dolor.{% endblock %}</title> {% if block('description') != '' %} <meta name="description" content="{% block description %}{% endblock %}"> {% endif %} <link href="..." rel="stylesheet" type="text/css"> {% block head_css %}{% endblock %} {% block head_javascript %}{% endblock %} </head> ...

Plantilla layout.twig<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>{% block title %}Lorem ipsum dolor.{% endblock %}</title> {% if block('description') != '' %} <meta name="description" content="{% block description %}{% endblock %}"> {% endif %} <link href="..." rel="stylesheet" type="text/css"> {% block head_css %}{% endblock %} {% block head_javascript %}{% endblock %} </head> ...

Plantilla layout.twig<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>{% block title %}Lorem ipsum dolor.{% endblock %}</title> {% if block('description') != '' %} <meta name="description" content="{% block description %}{% endblock %}"> {% endif %} <link href="..." rel="stylesheet" type="text/css"> {% block head_css %}{% endblock %} {% block head_javascript %}{% endblock %} </head> ...

Plantilla pagina1.twig

{% extends 'layout.twig' %}

{% block title %}Mi título{% endblock %}{% block description %} Lorem ipsum dolor sit amet.{% endblock %}

...

Plantilla pagina2.twig

{% extends 'layout.twig' %}

{% block title %}Otro título{% endblock %}{% block head_css %} <link href="/css/micrositio_especial.css" rel="stylesheet" type="text/css">{% endblock %}

...

Plantilla layout.twig<body id="{% block body_id %}{% endblock %}"> <div id="content">

{% block content %} <div id="main">

{% block main %}{% endblock %} </div>

<div id="side">

{% block side %}{% endblock %} </div>

{% endblock %} </div></body>

Plantilla layout.twig<body id="{% block body_id %}{% endblock %}"> <div id="content">

{% block content %} <div id="main">

{% block main %}{% endblock %} </div>

<div id="side">

{% block side %}{% endblock %} </div>

{% endblock %} </div></body>

Plantilla layout.twig<body id="{% block body_id %}{% endblock %}"> <div id="content">

{% block content %} <div id="main">

{% block main %}{% endblock %} </div>

<div id="side">

{% block side %}{% endblock %} </div>

{% endblock %} </div></body>

Plantilla layout.twig<body id="{% block body_id %}{% endblock %}"> <div id="content">

{% block content %} <div id="main">

{% block main %}{% endblock %} </div>

<div id="side">

{% block side %}{% endblock %} </div>

{% endblock %} </div></body>

Plantilla layout.twig<body id="{% block body_id %}{% endblock %}"> <div id="content">

{% block content %} <div id="main">

{% block main %}{% endblock %} </div>

<div id="side">

{% block side %}{% endblock %} </div>

{% endblock %} </div></body>

Plantilla pagina1.twig

{% extends 'layout.twig' %}{% block title %}Mi título{% endblock %}{% block description %}Lorem ipsum dolor sit amet.{% endblock %}

{% block main %} <h1>...</h1> <p>...</p>{% endblock %}

{% block side %} <ul>...</ul>{% endblock %}

Plantilla pagina2.twig

{% extends 'layout.twig' %}{% block title %}Otro título{% endblock %}{% block head_css %} <link href="/css/micrositio_especial.css" rel="stylesheet" type="text/css">{% endblock %}

{% block content %} <div> ... </div>{% endblock %}

CONCLUSIONES

Conclusiones• Twig mejora tu productividad y hace

que tus plantillas sean seguras.

Conclusiones• Twig mejora tu productividad y hace

que tus plantillas sean seguras.

• Drupal 8 utiliza actualmente el 10% de las posibilidades de Twig.

Conclusiones• Twig mejora tu productividad y hace

que tus plantillas sean seguras.

• Drupal 8 utiliza actualmente el 10% de las posibilidades de Twig.

• Twig es la parte más sencilla y divertida de la symfonización de Drupal.

REFERENCIAS

Referencias• Documentación:

twig.sensiolabs.org

• Recursos sobre Drupal + Twig:drupal.org/node/2008464

CONTACTO

Contacto

Javier Eguiluz

javiereguiluz.com

twitter.com/javiereguiluz

github.com/javiereguiluz

linkedin.com/in/javiereguiluz