TWIG
EL NUEVO MOTOR DE

PLANTILLAS PARA

DRUPAL 8
DRUPALCAMPSPAIN

JAVIER EGUILUZ

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
Javier Eguiluz
Formador + Programador

especializado en
nuevas tecnologías

Diseño y programación web

entusiasta del
fram...
empieza
desde cero

también
explica Twig

soporta todas las
versiones de
Symfony2
actualizaciones
gratuitas incluidas
AGENDA
PRIMERA PARTE

APRENDIENDO TWIG
SEGUNDA PARTE

TWIG AVANZADO
TERCERA PARTE

APLICANDO TWIG
PRIMERA PARTE

APRENDIENDO
TWIG
¿Qué es Twig?
• Twig es un motor y lenguaje de

plantillas (como PHP, Smarty,
Moustache, etc.)
• Twig es el sistema de pla...
Integrando Twig desde julio 2012
TWIG EN
DRUPAL 8
Nueva forma de pensar
$variables['table'] = theme('table', array(
'header' => $header, 'rows' => $rows
));
$variables['tab...
SINTAXIS
core/modules/node/templates/node.html.twig

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

{% hide(c...
core/modules/node/templates/node.html.twig

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

{% hide(c...
core/modules/node/templates/node.html.twig

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

{% hide(c...
core/modules/node/templates/node.html.twig

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

{% hide(c...
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 ...
Variables complejas
{{ articulo.titulo }}
{{ usuario.nombre }}
{{ producto.precio }}
{{ usuario.nombre }}
1.
2.
3.
4.
5.
6.

$usuario['nombre']
$usuario->nombre
$usuario->nombre()
$usuario->getNombre()
$usua...
Concatenando variables
El producto XXX cuesta NNN euros
{{ "El producto " ~ producto.titulo
~ " cuesta " ~ producto.precio...
Interpolando variables
El producto XXX cuesta NNN euros
{{ "El producto #{producto.titulo}
cuesta #{producto.precio} euros...
CREANDO
VARIABLES
Creando una nueva variable
{% set numero = 3 %}
El número elegido es {{ numero }}
{% set nombreCompleto =
nombre ~ ' ' ~ a...
Tipos de variables
{% set entero = 3 %}
{% set decimal = 3.14 %}
{% set cadena = "..." %}
{% set booleano = false %}
{% se...
Ejemplo de variable compleja
{# core/modules/node/templates/node.html.twig #}

node = {
'id':
1,
'bundle': 'page',
'author...
truco
Trozos de código como variables
{% set navegacion %}
<a href="...">Anterior</a>
...
...
<a href="...">Siguiente</a>
{% end...
Trozos de código como variables
{% set navegacion %}
<a href="...">Anterior</a>
...
...
<a href="...">Siguiente</a>
{% end...
FILTROS
Los filtros de Twig

Modifican la información
antes de mostrarla por
pantalla.
Sintaxis

{{ variable|filtro }}
Ejemplo de filtros para texto
lorEm iPsUm
{{ "..."|lower }}
{{ "..."|upper }}
{{ "..."|title }}
{{ "..."|capitalize }}

lo...
Los filtros que define Twig
abs
batch
capitalize
convert_encoding
date
date_modify
default
escape
first
format
join

json_...
Filtros con argumentos
{{ descripcion|striptags }}
{{ descripcion|striptags('<p>') }}
{{ precio|number_format }}
{{ precio...
Los filtros se adaptan
Tienes {{ amigos|length }} amigos

Tu nombre tiene {{ nombre|length }} letras
Los filtros se adaptan
Tienes {{ amigos|length }} amigos
count()
Tu nombre tiene {{ nombre|length }} letras
strlen()
Encadenando filtros
{{ titulo|striptags|title }}
{{ direcciones|first|trim|capitalize }}
truco
Aplicando filtros a varios elementos
<p>{{ nombre|striptags|trim }}</p>
<p>{{ apellidos|striptags|trim }}</p>
<p>{{ biogra...
Aplicando filtros a varios elementos
{% filter striptags|trim %}
<p>{{ nombre }}</p>
<p>{{ apellidos }}</p>
<p>{{ biografi...
LOS FILTROS DE
DRUPAL 8
El filtro para traducir contenidos

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

{{ 'Categories'|t }}: {{ c...
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 l...
Traduciendo contenidos variables
{# core/modules/aggregator/templates/aggregator-summary-items.html.twig #}

<a href="{{ s...
Traduciendo contenidos variables
{# core/modules/aggregator/templates/aggregator-summary-items.html.twig #}

<a href="{{ s...
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]) }}
Las funciones que define Twig
attribute
block
constant
cycle
date
dump
include

parent
random
range
template_from_string
ETIQUETAS
Las etiquetas de Twig
Ejecutan operaciones complejas
como la herencia de plantillas y
controlan la ejecución de la
plantil...
Las etiquetas que define Twig
autoescape
block
do
embed
extends
filter
flush

for
from
if
import
include
macro
sandbox

se...
Las etiquetas de control de flujo
PHP

if ... else
switch
return
break
continue

for
foreach
while
do ... while
goto

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

{% if label %}
<h2 {{ a...
La etiqueta IF básica
{# core/modules/block/templates/block.html.twig #}
<div>
✔ Existe la variable
{{ title_prefix }}
✔ N...
La etiqueta IF
{% if variable %}
...
{% endif %}
Tomando decisiones
{# core/modules/system/templates/page.html.twig #}

{% if title %}
<b><a href="...">{{ site_name }}</a>...
La etiqueta IF
{% if variable %}
...
{% else %}
...
{% endif %}
Tomando varias decisiones
{# core/modules/locale/templates/locale-translation-update-info.html.twig #}

{% if modules %}
<...
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="...
Condiciones múltiples
{# core/modules/book/templates/book-navigation.html.twig #}

{% if tree or has_links %}
<nav class="...
Condiciones múltiples
{% if not label_hidden %}
{% if not label_hidden or user.is_admin %}
{% if label_hidden and not user...
Comparaciones
{# core/modules/views/templates/views-view-grid.html.twig #}

{% if options.alignment == 'horizontal' %}
{# ...
Comparaciones
{# core/modules/views/templates/views-view-grid.html.twig #}

{% if options.alignment == 'horizontal' %}
{# ...
FECHAS
Intentando mostrar una fecha
{{ usuario.fechaNacimiento }}
ERROR

An exception has been thrown
during the rendering of a template:
"Catchable Fatal Error: Object of
class DateTime c...
Intentando mostrar una fecha
{{ usuario.fechaNacimiento }}
variable de tipo
DateTime
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...
Mostrando fechas
{{ usuario.fechaNacimiento|date }}
{{ ...|date('d/m/Y') }}
{{ ...|date('d/m/Y H:i:s') }}
{{ ...|date('d d...
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('+...
Modificando fechas
<p>
Activa tu cuenta antes del
{{ usuario.fechaRegistro
|date_modify('+1 week')|date }}
</p>
SEGUNDA PARTE

TWIG
AVANZADO
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 forumPostBreadcru...
Mostrando las migas de pan
<nav class="breadcrumb" role="navigation">
<ol>

{% for item in breadcrumb %}
<li>{{ item }}</l...
Mostrando las migas de pan
<nav class="breadcrumb" role="navigation">
<ol>

{% for item in breadcrumb %}
<li>{{ item }}</l...
Mostrando las migas de pan
<nav class="breadcrumb" role="navigation">
<ol>

{% for item in breadcrumb %}
<li>{{ item }}</l...
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) {...
El listado de libros
{# core/modules/book/book.module #}

function template_preprocess_book_all_books_block(&$variables) {...
Mostrando el listado de libros
{% for book_id, menu in book_menus %}
<nav id="book-block-menu-{{ book_id }}">
{{ menu }}
<...
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 }}
{...
La variable especial LOOP
{% for ... in coleccion %}
{{ loop.index }} 1, 2, 3, 4, 5, ...
{{ loop.index0 }} 0, 1, 2, 3, 4, ...
¿Y si no hay libros?
{% for book_id, menu in book_menus %}
<nav id="book-block-menu-{{ book_id }}">
{{ menu }}
</nav>

{% ...
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">

foru...
Indentando los mensajes del foro
<div class="indent">
<div class="indent">
<div class="indent">
<div class="indent">

sólo...
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|me...
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
esto destroza
tu página

<p>
<div> Lorem ipsum ... y no
cierro el div
</p>
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 ip...
La gran diferencia entre Twig y PHP
<h1>{{ titulo }}</h1>
<h1><?php echo $titulo; ?></h1>
TWIG

PHP

SEGURO

INSEGURO

POR...
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;...
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>
Utilizando bucles normales
<table>
{% for i in 1..9 %}
{% if 0 == i % 3 %}<tr>{% endif %}
<td>{{ i }}</td>
{% if 0 == i % ...
El filtro batch
<table>

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

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

{% endf...
El filtro batch
<table>

saca los elementos
de tres en tres

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

{% for columna in fila ...
Rellenando los huecos
<table>

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

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

!

EN DESARROLLO
TODO 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 va...
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 = ...
Activar la función dump()
// sites/default/settings.php
$settings['twig_debug'] = true;
<!-- THEME DEBUG -->
<!-- CALL: th...
Mejorando la depuración
• dump( ) es muy útil, pero no deja de

ser un simple var_dump( ).
• Resulta muy difícil depurar v...
LadyBug
Depurando aplicaciones
PHP como un profesional.
github.com/raulfraile/Ladybug

Raúl
Fraile
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....
Incluyendo un fragmento
...
{{ include('anuncio.twig') }}
...
Fragmento de código repetido
{# anuncio.twig #}
<script async src="//pagead2.googlesyndication.com/pagead/js/
adsbygoogle....
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_c...
Plantilla con muchos fragmentos
Plantilla con muchos fragmentos

include
HERENCIA DE
PLANTILLAS
plantilla

padre
plantilla

padre

igual para todas
las páginas
huecos

plantilla

padre

igual para todas
las páginas
Herencia de
plantillas

plantillas hija

plantilla padre
Herencia de
plantillas
en Twig se
llaman bloques
plantillas hija

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

bloques como quiera.
• La herencia permite, pero ...
Creando la plantilla padre.twig
<header> ... </header>
<div class="row">
<div class="span3"> HUECO 1 </div>
<div class="sp...
Creando la plantilla padre.twig
<header> ... </header>
<div class="row">
<div class="span3"> side </div>
<div class="span6...
Creando la plantilla padre.twig
<header> ... </header>
<div class="row">
<div class="span3">

{% block side %} {% endblock...
Creando la plantilla padre.twig
<header> ... </header>
<div class="row">
<div class="span3">

{% block side %} {% endblock...
Creando la plantilla padre.twig
<header> ... </header>
<div class="row">
<div class="span3">

{% block side %} {% endblock...
Creando la plantilla hija.twig
{% extends 'padre.twig' %}
Creando la plantilla hija.twig
{% extends 'padre.twig' %}
{% block main %}
...
{% endblock %}
{% block side %}
...
{% endb...
plantilla padre

plantilla hija

A

C

B

D
plantilla padre

plantilla hija

A

C

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock %...
plantilla padre

plantilla hija

A

C

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock %...
plantilla padre

plantilla hija

A

A

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock %...
plantilla padre

plantilla hija

A

A

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock %...
plantilla padre

plantilla hija

A

A
C

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock...
plantilla padre

plantilla hija

A

A
C

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock...
plantilla padre

plantilla hija

A

A
C

B

<div>{% block uno %}
A
{% endblock %}</div>
<div>{% block dos %}
B
{% endblock...
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.ini
extensi...
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

layout.twig

+
+

pagina1.twig
pagina2.twig

seccion1.twig
seccion2.twig

+

pagina1....
Plantilla layout.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Lorem ipsum dolor.{% en...
Plantilla layout.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Lorem ipsum dolor.{% en...
Plantilla layout.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Lorem ipsum dolor.{% en...
Plantilla layout.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Lorem ipsum dolor.{% en...
Plantilla pagina1.twig
{% extends 'layout.twig' %}
{% block title %}Mi título{% endblock %}
{% block description %}
Lorem ...
Plantilla pagina2.twig
{% extends 'layout.twig' %}
{% block title %}Otro título{% endblock %}
{% block head_css %}
<link h...
Plantilla layout.twig
<body id="{% block body_id %}{% endblock %}">
<div id="content">
{% block content %}
<div id="main">...
Plantilla layout.twig
<body id="{% block body_id %}{% endblock %}">
<div id="content">
{% block content %}
<div id="main">...
Plantilla layout.twig
<body id="{% block body_id %}{% endblock %}">
<div id="content">
{% block content %}
<div id="main">...
Plantilla layout.twig
<body id="{% block body_id %}{% endblock %}">
<div id="content">
{% block content %}
<div id="main">...
Plantilla layout.twig
<body id="{% block body_id %}{% endblock %}">
<div id="content">
{% block content %}
<div id="main">...
Plantilla pagina1.twig
{% extends 'layout.twig' %}
{% block title %}Mi título{% endblock %}
{% block description %}Lorem i...
Plantilla pagina2.twig
{% extends 'layout.twig' %}
{% block title %}Otro título{% endblock %}
{% block head_css %}
<link h...
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%...
Conclusiones
• Twig mejora tu productividad y hace

que tus plantillas sean seguras.
• Drupal 8 utiliza actualmente el 10%...
REFERENCIAS
Referencias
• Documentación:

twig.sensiolabs.org

• Recursos sobre Drupal + Twig:

drupal.org/node/2008464
CONTACTO
Contacto

Javier Eguiluz
twitter.com/javiereguiluz
github.com/javiereguiluz
linkedin.com/in/javiereguiluz

javiereguiluz.c...
Twig, el nuevo motor de plantillas de Drupal 8
Próxima SlideShare
Cargando en…5
×

Twig, el nuevo motor de plantillas de Drupal 8

3.421 visualizaciones

Publicado el

Publicado en: Tecnología
2 comentarios
8 recomendaciones
Estadísticas
Notas
Sin descargas
Visualizaciones
Visualizaciones totales
3.421
En SlideShare
0
De insertados
0
Número de insertados
406
Acciones
Compartido
0
Descargas
56
Comentarios
2
Recomendaciones
8
Insertados 0
No insertados

No hay notas en la diapositiva.

Twig, el nuevo motor de plantillas de Drupal 8

  1. 1. TWIG EL NUEVO MOTOR DE PLANTILLAS PARA DRUPAL 8 DRUPALCAMPSPAIN JAVIER EGUILUZ 26 OCTUBRE 2013
  2. 2. Licencia de esta presentación creativecommons.org/licenses/by-nc-sa/3.0/es
  3. 3. Muchas gracias a los patrocinadores Asociación Española de Drupal
  4. 4. ME PRESENTO
  5. 5. Javier Eguiluz Formador + Programador especializado en nuevas tecnologías Diseño y programación web entusiasta del framework Symfony Comunidad sobre el framework Symfony
  6. 6. empieza desde cero también explica Twig soporta todas las versiones de Symfony2 actualizaciones gratuitas incluidas
  7. 7. AGENDA
  8. 8. PRIMERA PARTE APRENDIENDO TWIG SEGUNDA PARTE TWIG AVANZADO TERCERA PARTE APLICANDO TWIG
  9. 9. PRIMERA PARTE APRENDIENDO TWIG
  10. 10. ¿Qué es Twig? • Twig es un motor y lenguaje de plantillas (como PHP, Smarty, Moustache, etc.) • Twig es el sistema de plantillas utilizado por Drupal 8.
  11. 11. Integrando Twig desde julio 2012
  12. 12. TWIG EN DRUPAL 8
  13. 13. Nueva forma de pensar $variables['table'] = theme('table', array( 'header' => $header, 'rows' => $rows )); $variables['table'] = array( '#theme' => 'table', '#header' => $header, '#rows' => $rows, ); D7 D8
  14. 14. SINTAXIS
  15. 15. core/modules/node/templates/node.html.twig <div {{ attributes }}> {# hide the comments to render them later #} {% hide(content.comments) %} {{ content }} </div>
  16. 16. core/modules/node/templates/node.html.twig <div {{ attributes }}> {# hide the comments to render them later #} {% hide(content.comments) %} {{ content }} </div> mostrar {{ ... }} información
  17. 17. core/modules/node/templates/node.html.twig <div {{ attributes }}> {# hide the comments to render them later #} {% hide(content.comments) %} {{ content }} </div> añadir {# ... #} comentarios
  18. 18. core/modules/node/templates/node.html.twig <div {{ attributes }}> {# hide the comments to render them later #} {% hide(content.comments) %} {{ content }} </div> ejecutar {% ... %} código
  19. 19. Sintaxis de Twig {{ mostrar información }} {% ejecutar código %} {# añadir comentario #}
  20. 20. MOSTRANDO INFORMACIÓN
  21. 21. Variables simples {{ titulo_articulo }} {{ nombre_usuario }} {{ precio }}
  22. 22. 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
  23. 23. Variables complejas {{ articulo.titulo }} {{ usuario.nombre }} {{ producto.precio }}
  24. 24. {{ usuario.nombre }} 1. 2. 3. 4. 5. 6. $usuario['nombre'] $usuario->nombre $usuario->nombre() $usuario->getNombre() $usuario->isNombre() null
  25. 25. Concatenando variables El producto XXX cuesta NNN euros {{ "El producto " ~ producto.titulo ~ " cuesta " ~ producto.precio ~ " euros" }} concatena variables
  26. 26. Interpolando variables El producto XXX cuesta NNN euros {{ "El producto #{producto.titulo} cuesta #{producto.precio} euros" }} interpola variables
  27. 27. CREANDO VARIABLES
  28. 28. Creando una nueva variable {% set numero = 3 %} El número elegido es {{ numero }} {% set nombreCompleto = nombre ~ ' ' ~ apellidos %}
  29. 29. 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} %}
  30. 30. 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 }
  31. 31. truco
  32. 32. Trozos de código como variables {% set navegacion %} <a href="...">Anterior</a> ... ... <a href="...">Siguiente</a> {% endset %}
  33. 33. Trozos de código como variables {% set navegacion %} <a href="...">Anterior</a> ... ... <a href="...">Siguiente</a> {% endset %} {{ navegacion }} {{ navegacion }}
  34. 34. FILTROS
  35. 35. Los filtros de Twig Modifican la información antes de mostrarla por pantalla.
  36. 36. Sintaxis {{ variable|filtro }}
  37. 37. Ejemplo de filtros para texto lorEm iPsUm {{ "..."|lower }} {{ "..."|upper }} {{ "..."|title }} {{ "..."|capitalize }} lorem ipsum LOREM IPSUM Lorem Ipsum Lorem ipsum
  38. 38. Los filtros que define Twig abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse slice sort split striptags title trim upper url_encode
  39. 39. Filtros con argumentos {{ descripcion|striptags }} {{ descripcion|striptags('<p>') }} {{ precio|number_format }} {{ precio|number_format(3) }} {{ precio|number_format(3, '.') }}
  40. 40. Los filtros se adaptan Tienes {{ amigos|length }} amigos Tu nombre tiene {{ nombre|length }} letras
  41. 41. Los filtros se adaptan Tienes {{ amigos|length }} amigos count() Tu nombre tiene {{ nombre|length }} letras strlen()
  42. 42. Encadenando filtros {{ titulo|striptags|title }} {{ direcciones|first|trim|capitalize }}
  43. 43. truco
  44. 44. Aplicando filtros a varios elementos <p>{{ nombre|striptags|trim }}</p> <p>{{ apellidos|striptags|trim }}</p> <p>{{ biografia|striptags|trim }}</p>
  45. 45. Aplicando filtros a varios elementos {% filter striptags|trim %} <p>{{ nombre }}</p> <p>{{ apellidos }}</p> <p>{{ biografia }}</p> {% endfilter %}
  46. 46. LOS FILTROS DE DRUPAL 8
  47. 47. El filtro para traducir contenidos {{ '...'|t }}
  48. 48. 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>
  49. 49. Traduciendo contenidos variables 'More posts about Drupal 8' 'More posts about Twig' 'More posts about Symfony'
  50. 50. Traduciendo contenidos variables 'More posts about Drupal 8' 'More posts about Twig' 'More posts about Symfony' traducir la parte fija considerarlo una variable
  51. 51. 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}) }}
  52. 52. 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}) }}
  53. 53. FUNCIONES
  54. 54. Las funciones de Twig Generan información para mostrarla por pantalla.
  55. 55. Sintaxis {{ funcion() }} {{ funcion('...') }} {{ funcion('...', '...') }}
  56. 56. Ejemplo de función de Twig {{ random() }} {{ random(10) }} {{ random("abcde") }} {{ random([1, 2, 3]) }}
  57. 57. Las funciones que define Twig attribute block constant cycle date dump include parent random range template_from_string
  58. 58. ETIQUETAS
  59. 59. Las etiquetas de Twig Ejecutan operaciones complejas como la herencia de plantillas y controlan la ejecución de la plantilla.
  60. 60. Las etiquetas que define Twig autoescape block do embed extends filter flush for from if import include macro sandbox set spaceless use verbatim
  61. 61. Las etiquetas de control de flujo PHP if ... else switch return break continue for foreach while do ... while goto TWIG if ... else for
  62. 62. LA ETIQUETA IF
  63. 63. 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>
  64. 64. La etiqueta IF básica {# core/modules/block/templates/block.html.twig #} <div> ✔ Existe la variable {{ title_prefix }} ✔ No es null {% if label %} ✔ No es cadena vacía <h2 {{ attributes }}>{{ label }}</h2> {% endif %} {{ title_suffix }} </div>
  65. 65. La etiqueta IF {% if variable %} ... {% endif %}
  66. 66. 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 %}
  67. 67. La etiqueta IF {% if variable %} ... {% else %} ... {% endif %}
  68. 68. 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 %}
  69. 69. La etiqueta IF {% if variable %} ... {% elseif variable %} ... {% else %} ... {% endif %}
  70. 70. 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 %}
  71. 71. 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 and b-and or b-or not b-xor
  72. 72. 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 %}
  73. 73. 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' %}
  74. 74. 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 with < <= matches
  75. 75. FECHAS
  76. 76. Intentando mostrar una fecha {{ usuario.fechaNacimiento }}
  77. 77. ERROR An 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"
  78. 78. Intentando mostrar una fecha {{ usuario.fechaNacimiento }} variable de tipo DateTime
  79. 79. Mostrando fechas {{ usuario.fechaNacimiento|date }}
  80. 80. Mostrando fechas {{ usuario.fechaNacimiento|date }} {{ ...|date('d/m/Y') }} {{ ...|date('d/m/Y H:i:s') }}
  81. 81. Mostrando fechas {{ usuario.fechaNacimiento|date }} {{ ...|date('d/m/Y') }} {{ ...|date('d/m/Y H:i:s') }} {{ ...|date('d de F de Y') }}
  82. 82. Mostrando fechas {{ usuario.fechaNacimiento|date }} {{ ...|date('d/m/Y') }} {{ ...|date('d/m/Y H:i:s') }} {{ ...|date('d de F de Y') }} 26 de Octubre de 2013
  83. 83. truco
  84. 84. Creando fechas {{ 'now'|date }} {{ 'today'|date }} {{ 'next Monday'|date }} {{ '+ 10 minutes'|date }}
  85. 85. Creando fechas {{ 'now'|date }} {{ 'today'|date }} {{ 'next Monday'|date }} {{ '+ 10 minutes'|date }} strtotime()
  86. 86. Creando fechas <footer> © {{ 'now'|date('Y') }} ACME.org </footer>
  87. 87. Modificando fechas {{ usuario.fechaNacimiento |date_modify('-9 months')|date }} {{ usuario.fechaNacimiento |date_modify('+18 years')|date }}
  88. 88. Modificando fechas <p> Activa tu cuenta antes del {{ usuario.fechaRegistro |date_modify('+1 week')|date }} </p>
  89. 89. SEGUNDA PARTE TWIG AVANZADO
  90. 90. BUCLES Y COLECCIONES
  91. 91. Colecciones Array (asociativo o numérico) o un objeto que implemente la interfaz Traversable.
  92. 92. Secuencias {{ 1..3 }} [1, 2, 3] {{ 5..2 }} [5, 4, 3, 2] {{ 'a'..'d' }} ['a', 'b', 'c', 'd']
  93. 93. 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; }
  94. 94. Mostrando las migas de pan <nav class="breadcrumb" role="navigation"> <ol> {% for item in breadcrumb %} <li>{{ item }}</li> {% endfor %} </ol> </nav>
  95. 95. Mostrando las migas de pan <nav class="breadcrumb" role="navigation"> <ol> {% for item in breadcrumb %} <li>{{ item }}</li> {% endfor %} </ol> </nav>
  96. 96. Mostrando las migas de pan <nav class="breadcrumb" role="navigation"> <ol> {% for item in breadcrumb %} <li>{{ item }}</li> {% endfor %} </ol> </nav>
  97. 97. El bucle FOR {% for valor in coleccion %} ... {% endfor %}
  98. 98. 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]; } }
  99. 99. 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] = ...
  100. 100. Mostrando el listado de libros {% for book_id, menu in book_menus %} <nav id="book-block-menu-{{ book_id }}"> {{ menu }} </nav> {% endfor %}
  101. 101. El bucle FOR {% for clave, valor in coleccion %} ... {% endfor %}
  102. 102. Accediendo a las claves de la colección {% for clave in coleccion|keys %} ... {% endfor %}
  103. 103. truco
  104. 104. La variable especial LOOP {% for ... in coleccion %} {{ loop.index }} {{ loop.index0 }} {{ loop.first }} {{ loop.last }} {{ loop.length }} {% endfor %}
  105. 105. La variable especial LOOP {% for ... in coleccion %} {{ loop.index }} 1, 2, 3, 4, 5, ... {{ loop.index0 }} 0, 1, 2, 3, 4, ... true, false, false, ... {{ loop.first }} ..., false, false, true {{ loop.last }} {{ loop.length }} 5 {% endfor %}
  106. 106. ¿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 %}
  107. 107. El bucle FOR {% for valor in coleccion %} ... {% else %} ... {% endfor %}
  108. 108. Indentando los mensajes del foro <div class="indent"> <div class="indent"> <div class="indent"> <div class="indent"> forum.depth Lorem ipsum dolor sit amet, consectetur adipisic ingelit, sed do eiusmodtempor incididunt ut labore et dolore magna aliqua. </div> </div> </div> </div>
  109. 109. Indentando los mensajes del foro <div class="indent"> <div class="indent"> <div class="indent"> <div class="indent"> sólo si depth es mayor que cero forum.depth Lorem ipsum dolor sit amet, consectetur adipisic ingelit, sed do eiusmodtempor incididunt ut labore et dolore magna aliqua. </div> </div> </div> </div>
  110. 110. Indentando los mensajes del foro {% for i in 1..forum.depth if forum.depth > 0 %} <div class="indent"> {% endfor %}
  111. 111. El bucle FOR {% for valor in coleccion if condicion %} ... {% endfor %}
  112. 112. El bucle FOR completo {% for clave, valor in coleccion if condicion %} ... {% else %} ... {% endfor %}
  113. 113. Los filtros para colecciones {% for ... in coleccion|sort %} {% for ... in coleccion|reverse %} {% for ... in coleccion|merge(otra_coleccion) %} {% for ... in coleccion|slice(1, 3) %}
  114. 114. ESCAPANDO INFORMACIÓN
  115. 115. Este código es peligroso <p> <?php echo $descripcion; ?> </p>
  116. 116. Código mal formado <p> <div> Lorem ipsum ... y no cierro el div </p>
  117. 117. Código mal formado esto destroza tu página <p> <div> Lorem ipsum ... y no cierro el div </p>
  118. 118. La solución PHP <p><?php echo htmlspecialchars( $descripcion, ENT_QUOTES, 'UTF-8') ?> </p>
  119. 119. La solución Twig <p> {{ descripcion }} </p>
  120. 120. 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;
  121. 121. La gran diferencia entre Twig y PHP <h1>{{ titulo }}</h1> <h1><?php echo $titulo; ?></h1> TWIG PHP SEGURO INSEGURO POR DEFECTO POR DEFECTO
  122. 122. El filtro raw {{ descripcion|raw }} <strong>Lorem ipsum</strong> dolor sit <em>amet</em>
  123. 123. El filtro escape {{ descripcion|e }} &lt;strong&gt;Lorem ipsum&lt;/ strong&gt; dolor sit &lt;em&gt;amet&lt;/em&gt;
  124. 124. 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') }} x3Cstrongx3ELoremx20ipsumx3Cx2Fstrongx3E x20dolorx20sitx20x3Cemx3Eametx3Cx2Fem x3E
  125. 125. BATCH
  126. 126. Segmentando listas 1 2 3 4 5 6 7 8 9
  127. 127. Utilizando bucles normales <table> {% for i in 1..9 %} <td>{{ i }}</td> {% endfor %} </table>
  128. 128. Utilizando bucles normales <table> {% for i in 1..9 %} {% if 0 == i % 3 %}<tr>{% endif %} <td>{{ i }}</td> {% if 0 == i % 3 %}</tr>{% endif %} {% endfor %} </table>
  129. 129. El filtro batch <table> {% for fila in 1..9|batch(3) %} <tr> {% for columna in fila %} <td> {{ columna }} </td> {% endfor %} </tr> {% endfor %} </table>
  130. 130. El filtro batch <table> saca los elementos de tres en tres {% for fila in 1..9|batch(3) %} <tr> {% for columna in fila %} <td> {{ columna }} </td> {% endfor %} </tr> {% endfor %} </table>
  131. 131. Rellenando los huecos <table> {% for fila in 1..7|batch(3, '-') %} <tr> {% for columna in fila %} <td> {{ columna }} </td> {% endfor %} </tr> {% endfor %} </table>
  132. 132. 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 - -
  133. 133. DEPURACIÓN
  134. 134. DEPURACIÓN ! EN DESARROLLO TODO ESTO PODRÍA CAMBIAR EN LA VERSIÓN ESTABLE DE DRUPAL 8
  135. 135. Mostrar el contenido de variables {{ dump(variable) }} {{ dump(variable1, variable2) }} {{ dump() }}
  136. 136. Mostrar el contenido de variables {{ dump(variable) }} {{ dump(variable1, variable2) }} {{ dump() }} muestra TODAS las variables
  137. 137. Activar la función dump() // sites/default/settings.php $settings['twig_debug'] = true;
  138. 138. Activar la función dump() // sites/default/settings.php $settings['twig_debug'] = true; twig_debug = false twig_debug = true
  139. 139. Activar la función dump() // sites/default/settings.php $settings['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> twig_debug <html ... = false twig_debug = true
  140. 140. 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.
  141. 141. LadyBug Depurando aplicaciones PHP como un profesional. github.com/raulfraile/Ladybug Raúl Fraile
  142. 142. Depurando con LadyBug $result = mysql_query('SELECT * FROM user', $conn); ladybug_dump($result);
  143. 143. Depurando con LadyBug $var = new Foo(); ladybug_dump($var);
  144. 144. FRAGMENTOS DE PLANTILLAS
  145. 145. Plantillas con fragmentos repetidos
  146. 146. Plantillas con fragmentos repetidos
  147. 147. 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>
  148. 148. Incluyendo un fragmento ... {{ include('anuncio.twig') }} ...
  149. 149. 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>
  150. 150. Incluyendo un fragmento con variables ... {{ include('anuncio.twig', { ... }) }} ...
  151. 151. Incluyendo un fragmento con variables ... {{ include('anuncio.twig', { ad: { 'style': '...', 'client': '...', 'slot': '...' }}) }} ...
  152. 152. Fragmentos sin variables {{ include( 'anuncio.twig', with_context = false ) }} {{ include( 'anuncio.twig', { ... }, with_context = false ) }}
  153. 153. Plantilla con muchos fragmentos
  154. 154. Plantilla con muchos fragmentos include
  155. 155. HERENCIA DE PLANTILLAS
  156. 156. plantilla padre
  157. 157. plantilla padre igual para todas las páginas
  158. 158. huecos plantilla padre igual para todas las páginas
  159. 159. Herencia de plantillas plantillas hija plantilla padre
  160. 160. Herencia de plantillas en Twig se llaman bloques plantillas hija plantilla padre
  161. 161. 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.
  162. 162. 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>
  163. 163. 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>
  164. 164. 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>
  165. 165. 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>
  166. 166. Creando la plantilla padre.twig <header> ... </header> <div class="row"> <div class="span3"> {% block side %} {% endblock %} los nombres NO </div> <div class="span6"> llevan comillas {% block main %} {% endblock %} </div> <div class="span3"> ... </div> </div> <footer> ... </footer>
  167. 167. Creando la plantilla hija.twig {% extends 'padre.twig' %}
  168. 168. Creando la plantilla hija.twig {% extends 'padre.twig' %} {% block main %} ... {% endblock %} {% block side %} ... {% endblock %}
  169. 169. plantilla padre plantilla hija A C B D
  170. 170. plantilla padre plantilla hija A C B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D
  171. 171. plantilla padre plantilla hija A C B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D {% extends 'padre.twig' %} {% block uno %} C {% endblock %} {% block dos %} D {% endblock %}
  172. 172. plantilla padre plantilla hija A A B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D
  173. 173. plantilla padre plantilla hija A A B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D {% extends 'padre.twig' %} {% block dos %} D {% endblock %}
  174. 174. plantilla padre plantilla hija A A C B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D
  175. 175. plantilla padre plantilla hija A A C B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D {% extends 'padre.twig' %} {% block uno %} {{ parent() }} C {% endblock %} {% block dos %} D {% endblock %}
  176. 176. plantilla padre plantilla hija A A C B <div>{% block uno %} A {% endblock %}</div> <div>{% block dos %} B {% endblock %}</div> D {% extends 'padre.twig' %} {% block uno %} {{ parent() }} C {% endblock %} {% block dos %} D {% endblock %}
  177. 177. RENDIMIENTO
  178. 178. esta es la parte más lenta de Twig
  179. 179. Instalando la extensión de Twig $ pear channel-discover pear.twig-project.org $ pear install twig/CTwig ; php.ini extension=twig.so
  180. 180. Instalando la extensión de Twig +15% SIN extensión CON extensión
  181. 181. TERCERA PARTE APLICANDO TWIG
  182. 182. DISEÑANDO SITIOS COMPLEJOS
  183. 183. Jerarquía de plantillas layout.twig layout.twig + + pagina1.twig pagina2.twig seccion1.twig seccion2.twig + pagina1.twig pagina2.twig
  184. 184. 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> ...
  185. 185. 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> ...
  186. 186. 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> ...
  187. 187. 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> ...
  188. 188. Plantilla pagina1.twig {% extends 'layout.twig' %} {% block title %}Mi título{% endblock %} {% block description %} Lorem ipsum dolor sit amet. {% endblock %} ...
  189. 189. 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 %} ...
  190. 190. 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>
  191. 191. 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>
  192. 192. 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>
  193. 193. 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>
  194. 194. 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>
  195. 195. 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 %}
  196. 196. 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 %}
  197. 197. CONCLUSIONES
  198. 198. Conclusiones • Twig mejora tu productividad y hace que tus plantillas sean seguras.
  199. 199. Conclusiones • Twig mejora tu productividad y hace que tus plantillas sean seguras. • Drupal 8 utiliza actualmente el 10% de las posibilidades de Twig.
  200. 200. 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.
  201. 201. REFERENCIAS
  202. 202. Referencias • Documentación: twig.sensiolabs.org • Recursos sobre Drupal + Twig: drupal.org/node/2008464
  203. 203. CONTACTO
  204. 204. Contacto Javier Eguiluz twitter.com/javiereguiluz github.com/javiereguiluz linkedin.com/in/javiereguiluz javiereguiluz.com

×