More Related Content Similar to Twig avanzado (sf2Vigo) (20) More from Javier Eguiluz (18) Twig avanzado (sf2Vigo)2. me presento
• Javier Eguiluz
• formador en Symfony2 y
nuevas tecnologías
5. objetivos de la sesión
• Buenas prácticas
• Trucos
• Usos avanzados
• Snipets
6. Si no sabes Twig, te vas a
perder a partir de la
siguiente transparencia
16. TWIG
{{ usuario.nombre }}
PHP
<?php echo htmlspecialchars($usuario->
getNombre(), ENT_QUOTES, 'UTF-8'); ?>
19. <p> Hola {{ usuario }}
Tienes {{ edad }} años y
vives en {{ ciudad }} </p>
20. <p> Hola {{ usuario.nombre }}
Tienes {{ usuario.edad }}
años y vives en
{{ usuario.ciudad }} </p>
22. {{ usuario.nombre }}
1. $usuario["nombre"]
2. $usuario->nombre
3. $usuario->nombre()
4. $usuario->getNombre()
5. $usuario->isNombre()
6. null
23. <?php Template.php
abstract class Twig_Template implements
Twig_TemplateInterface
{
// ...
protected function getAttribute(
$object,
$item,
array $arguments = array(),
$type = Twig_TemplateInterface::ANY_CALL,
$isDefinedTest = false) {
// ...
41. {% for clave, elemento
in coleccion %}
{# ... #}
{% endfor %}
42. {% if condicion1 %}
{# ... #}
{% elseif condicion2 %}
{# ... #}
{% else %}
{# ... #}
{% endif %}
47. # TITULO # layout.twig
# LATERAL #
# CONTENIDOS #
48. <html> <head> ... </head> layout.twig
<body>
<h1>
{% block titulo %}{% endblock %}
</h1>
{% block contenidos %}{% endblock %}
{% block lateral %}{% endblock %}
</body></html>
49. <html> <head> ... </head> portada.twig
<body>
<h1>
PORTADA
</h1>
<div id="contenidos">...</div>
<div id="lateral">...</div>
</body></html>
50. <html> <head> ... </head> portada.twig
<body>
<h1>
PORTADA
</h1>
<div id="contenidos">...</div>
<div id="lateral">...</div>
</body></html>
53. {% extends "layout.twig" %} portada.twig
{% block titulo %}
PORTADA
{% endblock %}
{% block contenidos %}
<div id="contenidos">...</div>
{% endblock %}
{% block lateral %}
<div id="lateral">...</div>
{% endblock %}
54. {% extends "layout.twig" %}
contacto.twig
{% block titulo %}
CONTACTO
{% endblock %}
{% block contenidos %}
<form>...</form>
{% endblock %}
{% block lateral %}
<p>...</p>
{% endblock %}
56. DESARROLLO
WEB ÁGIL CON todos los ejemplos que se muestran
SYMFONY2 a continuación pertenecen al libro
Desarrollo web ágil
con Symfony2
(disponible próximamente)
Javier Eguiluz
59. # app/config/config.yml
twig:
# ...
globals:
cp: 01001
iva: [1.04, 1.08, 1.18]
version: 1.0.3
Precio {{ oferta.precio * iva[0] }}
Coste de envío a {{ usuario.cp | default(cp) }}
<footer>
© 'now'|date('Y') - v.{{ version }}
</footer>
61. # app/config/config.yml
twig:
# ...
globals:
global:
cp: 01001
iva: [1.04, 1.08, 1.18]
version: 1.0.3
Precio {{ oferta.precio * global.iva[0] }}
Coste de envío a {{ oferta.cp | default(global.cp) }}
<footer>
© 'now'|date('Y') - v.{{ global.version }}
</footer>
62. servicios como variables globales
namespace CuponOfertaBundleUtil;
class Util
{
static public function getSlug($cadena)
{
// ...
return $slug;
}
}
71. {% for articulo in articulos %}
{{ articulo.titulo }}
{# ... #}
{% endfor %}
72. {% for articulo in articulos %}
{{ articulo.titulo }}
{# ... #}
{% else %}
No hay artículos
{% endfor %}
75. {% for oferta in ofertas
if oferta.precio < 10 %}
{# ... #}
{% endfor %}
77. Itera sólamente por los
amigos del usuario
{% set usuarios = 1..30 %}
{% set amigos = [12, 29, 34, 55, 67] %}
78. {% set usuarios = 1..30 %}
{% set amigos = [12, 29, 34, 55, 67] %}
{% for usuario in usuarios
if usuario in amigos %}
{# sólo 12 y 29 #}
{% endfor %}
80. operación resultado
{{ 12 / 7 }} 1.7142857142
{{ 12 // 7 }} 1
{{ 12 % 7 }} 5
82. {% set nombre = 'José García' %}
{% set edad = 27 %}
{% set precio = 104.83 %}
{% set conectado = false %}
{% set tasaImpuestos = [4, 8, 18] %}
83. {% set perfil = {
'nombre': 'José García',
'perfiles': ['usuario', 'admin'],
'edad': 27,
'validado': true
} %}
85. {% set perfil %}
Nombre: {{ usuario.nombre }}
Apellidos: {{ usuario.apellidos }}
Edad: {{ usuario.edad }} años
Página: {{ usuario.url }}
{% endset %}
{{ perfil }}
86. {% set nombre, edad, activado =
'José', 27, false %}
{{ nombre }}
{{ edad }}
{% if activado %}
109. {# formulario.html.twig #}
{% macro campo(nombre, tipo, valor) %}
<input type="{{ tipo }}"
name="{{ nombre }}"
value="{{ valor }}" />
{% endmacro %}
111. {% from 'formularios.html.twig'
import campo as campo %}
<table>
{{ campo('nombre', 'text', 'José') }}
{{ campo('apellidos', 'text', 'García Pérez') }}
{{ campo('telefono', 'text') }}
</table>
112. {% from 'formularios.html.twig'
import campo as campo %}
<table>
{{ campo('nombre', 'text', 'José') }}
{{ campo('apellidos', 'text', 'García Pérez') }}
{{ campo('telefono', 'text') }}
</table>
<ul>
{{ campo('nombre', 'text', 'José') }}
{{ campo('apellidos', 'text', 'García Pérez') }}
{{ campo('telefono', 'text') }}
</ul>
113. {# formulario.html.twig #}
{% macro campo(nombre, tipo, valor) %}
<input type="{{ tipo }}" name="{{ nombre }}"
value="{{ valor }}" />
{% endmacro %}
114. {# formulario.html.twig #}
{% macro campo(nombre, tipo, valor) %}
<input type="{{ tipo }}" name="{{ nombre }}"
value="{{ valor }}" />
{% endmacro %}
{% macro fila(nombre, tipo, valor) %}
<tr>
<td>{{ nombre | capitalize }}</td>
<td>{{ _self.campo(nombre, tipo, valor) }}</td>
</tr>
{% endmacro %}
115. {# formulario.html.twig #}
{% macro campo(nombre, tipo, valor) %}
<input type="{{ tipo }}" name="{{ nombre }}"
value="{{ valor }}" />
{% endmacro %}
116. {# formulario.html.twig #}
{% macro campo(nombre, tipo, valor) %}
<input type="{{ tipo }}" name="{{ nombre }}"
value="{{ valor }}" />
{% endmacro %}
{% macro item(nombre, tipo, valor) %}
<li>
{{ _self.campo(nombre, tipo, valor) }}
</li>
{% endmacro %}
117. {% from 'formularios.html.twig'
import campo as campo %}
{{ campo('nombre', 'text', 'José') }}
{{ campo('apellidos', 'text', 'García Pérez') }}
{{ campo('telefono', 'text') }}
118. {% from 'formularios.html.twig'
import fila as campo %}
<table>
{{ campo('nombre', 'text', 'José') }}
{{ campo('apellidos', 'text', 'García Pérez') }}
{{ campo('telefono', 'text') }}
</table>
119. {% from 'formularios.html.twig'
import item as campo %}
<ul>
{{ campo('nombre', 'text', 'José') }}
{{ campo('apellidos', 'text', 'García Pérez') }}
{{ campo('telefono', 'text') }}
</ul>
121. public function getFilters()
{
return array('longitud' => new
Twig_Filter_Method($this,
'longitud')
);
}
function longitud($valor)
{
return strlen($valor);
}
122. public function getFilters()
{
return array('longitud' => new
Twig_Filter_Method($this,
'longitud')
);
}
function longitud($valor)
{
return strlen($valor);
}
127. class Twig_Environment
{
const VERSION = '1.1.2';
// ...
$options = array_merge(array(
'debug' => false,
'charset' => 'UTF-8',
'base_template_class' => 'Twig_Template',
'strict_variables' => false,
'autoescape' => true,
'cache' => false,
'auto_reload' => null,
'optimizations' => -1,
), $options);
// ...
}
139. # app/config/config.yml
twig:
autoescape: true
auto_reload: ~
cache: %kernel.cache_dir%/twig
charset: %kernel.charset%
debug: %kernel.debug%
strict_variables: ~
140. $twig = new Twig_Environment($loader, array(
'debug' => true,
'strict_variables' => true,
'charset' => 'UTF-8',
'cache' => __DIR__.'/cache'
));
141. # app/config/config.yml
twig:
base_template_class: Twig_Template
<?php
class __TwigTemplate_82262eae3f96052ef64432a9ddc53915
extends Twig_Template
{
protected $parent;
public function __construct(Twig_Environment $env)
{
// ...
}
142. # app/config/config.yml
twig:
base_template_class: Twig_Template
<?php
class __TwigTemplate_82262eae3f96052ef64432a9ddc53915
extends Twig_Template
{
protected $parent;
public function __construct(Twig_Environment $env)
{
// ...
}
148. modificar campos de una plantilla
{{ form_row(noticia.url) }}
Label
{% block url_widget %}
{% spaceless %}
{% set type = type|default('url') %}
{{ block('field_widget') }}
{% endspaceless %}
{% endblock url_widget %}
149. {{ form_row(noticia.url) }}
{% form_theme form _self %}
{% block url_widget %}
{% set type = 'url' %}
<em>http://</em> {{ block('field_widget') }}
{% endblock url_widget %}
150. {{ form_row(noticia.url) }}
{% form_theme form _self %}
{% block url_widget %}
{% set type = 'url' %}
<em>http://</em> {{ block('field_widget') }}
{% endblock url_widget %}
151. {{ form_row(noticia.url) }}
{% form_theme form _self %}
{% block url_widget %}
{% set type = 'url' %}
<em>http://</em> {{ block('field_widget') }}
{% endblock url_widget %}
Label http://
152. modificar campos de varias plantillas
{# src/.../Resources/views/Form/form.html.twig #}
{% block url_widget %}
{% set type = 'url' %}
<em>http://</em> {{ block('field_widget') }}
{% endblock url_widget %}
153. {% form_theme form
'MiBundle:Form:form.html.twig' %}
{{ form_row(noticia.titular) }}
{{ form_row(noticia.publicada) }}
{{ form_row(noticia.url) }}
154. modificar todos los formularios
# app/config/config.yml
twig:
# ...
form:
resources:
- 'form_div_layout.html.twig'
156. {% use "form_div_layout.html.twig" %}
{% block field_row %}
{% spaceless %}
<tr>
<td>
{{ form_label(form, label|default(null)) }}
</td>
<td>
{{ form_errors(form) }}
{{ form_widget(form) }}
</td>
</tr>
{% endspaceless %}
{% endblock field_row %}
{# ... #}
157. {% use "form_div_layout.html.twig" %}
{% block field_row %}
{# ... #}
{% endblock %}
{% block form_errors %}
{# ... #}
{% endblock %}
{% block hidden_row %}
{# ... #}
{% endblock %}
{% block form_widget %}
{# ... #}
{% endblock %}
162. {{ form_label(fecha) }}
{{ form_errors(fecha) }}
{{ form_widget(fecha.year) }}
{{ form_widget(fecha.month) }}
{{ form_widget(fecha.day) }}
165. public function indexAction() Symfony2
{
$em = $this->getDoctrine()->getEntityManager();
$entities = $em->getRepository('{{ bundle }}:{{ entity }}')
->findAll();
{% if 'annotation' == format %}
return array('entities' => $entities);
{% else %}
return $this->render('{{ bundle }}:
{{ entity|replace({'': '/'}) }}:index.html.twig',
array('entities' => $entities));
{% endif %}
}
166. easybook3
/* page size, margins, headers & footers
--------------------------------------------- */
@page {
size: {{ edition.page_size }};
}
{% if edition.two_sided %}
@page:right {
margin: {{ edition.margin.top|default('25mm') }}
{{ edition.margin.outter|default('20mm') }}
{{ edition.margin.bottom|default('25mm') }}
{{ edition.margin.inner|default('30mm') }};
@top-left {
/* ... */
}
167. {% block NamespaceDeclaration %}
{% if namespace %} Doctrine2
namespace {{ namespace }}; ActiveRecord
use {{ namespace }}Base{{ classname }} as Base{{ classname }};
{% else %}
use Base{{ classname }} as Base{{ classname }};
{% endif %}
{% endblock %}
{% block DocBlock %}
/**
* ActiveRecord class.
*/
{% endblock %}
{% block ClassDeclaration %}
class {{ classname }} extends Base{{ classname }}
{% endblock %}
{
{% block Body %}
// add your code here
{% endblock %}
}
172. <select id="ciudad">
{% for ciudad in ciudades %}
<option value="{{ ciudad.slug }}">
{{ ciudad.nombre }}
</option>
{% endfor %}
</select>
173. <script type="text/javascript">
var lista = document.getElementById('ciudad');
var ciudad = lista.options[lista.selectedIndex].value;
lista.onchange = function() {
var url = {{ path('portada', {'ciudad': ciudad }) }};
window.location = url;
};
</script>
174. <script type="text/javascript">
var lista = document.getElementById('ciudad');
var ciudad = lista.options[lista.selectedIndex].value;
lista.onchange = function() {
var url = {{ path('portada', {'ciudad': ciudad }) }};
window.location = url;
};
</script>
175. <script type="text/javascript">
var lista = document.getElementById('ciudad');
var ciudad = lista.options[lista.selectedIndex].value;
lista.onchange = function() {
var url = Routing.generate('portada',
{'ciudad': ciudad});
window.location = url;
};
</script>
176. <script type="text/javascript" src="
{{ asset('bundles/fosjsrouting/js/router.js') }}
"></script>
<script type="text/javascript" src="
{{ path('fos_js_routing_js', {"callback":
"fos.Router.setData"}) }}
"></script>
<script type="text/javascript">
var lista = document.getElementById('ciudad');
var ciudad = lista.options[lista.selectedIndex].value;
lista.onchange = function() {
var url = Routing.generate('portada',
{'ciudad': ciudad});
window.location = url;
};
</script>
180. <script type="text/javascript" src="twig.js"></script>
<script type="text/javascript" src="perfil.js"></script>
<script type="text/javascript">
alert(Twig.render(perfil, { nombre:
'José', apellidos: 'Pérez' }));
</script>
183. {{ ... | length }}
Tienes {{ amigos|length }} amigos
y tu nombre tiene
{{ nombre|length }} letras
184. {{ ... | length }}
count( )
Tienes {{ amigos|length }} amigos
y tu nombre tiene
{{ nombre|length }} letras
185. {{ ... | length }}
count( )
Tienes {{ amigos|length }} amigos
y tu nombre tiene
{{ nombre|length }} letras
strlen( )
186. {{ ... in ... }}
{% if fecha in ['2005', '2006'] %}
Eres un early-adopter
{% endif %}
{% if password in login %}
La contraseña no puede ser
una parte del login
{% endif %}
187. {{ ... in ... }}
in_array( )
{% if fecha in ['2005', '2006'] %}
Eres un early-adopter
{% endif %}
{% if password in login %}
La contraseña no puede ser
una parte del login
{% endif %}
188. {{ ... in ... }}
in_array( )
{% if fecha in ['2005', '2006'] %}
Eres un early-adopter
{% endif %}
strpos( )
{% if password in login %}
La contraseña no puede ser
una parte del login
{% endif %}
189. {% for letra in 'a'|upper..inicial|default('z')|upper %}
{{ letra }}
{% endfor %}
190. {% for letra in 'a'|upper..inicial|default('z')|upper %}
{{ letra }}
{% endfor %}
{% filter upper %}
{% for letra in 'a'..inicial|default('z') %}
{{ letra }}
{% endfor %}
{% endfilter %}
191. {% for letra in 'a'|upper..inicial|default('z')|upper %}
{{ letra }}
{% endfor %}
{% filter upper %}
{% for letra in 'a'..inicial|default('z') %}
{{ letra }}
{% endfor %}
{% endfilter %}
{% for letra in 'a'..inicial|default('z') %}
{{ letra | upper }}
{% endfor %}
196. {% set bundles = {
'AsseticBundle' => '.../vendor/...',
'BackendBundle' => '.../src/...',
'CiudadBundle' => '.../src/...',
'DoctrineBundle' => '.../vendor/...',
...
} %}
199. {% for name in bundles|keys|sort %}
<tr>
<th>{{ name }}</th>
<td>{{ bundles[name] }}</td>
</tr>
{% endfor %}
201. {% set usuarios = [
{ 'email': '..@..' },
{ 'movil': '9....' }
] %}
{% for usuario in usuarios %}
{{ usuario.nombre }}
Contacto {{ usuario.????? }}
{% endfor %}
202. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
203. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
{{ usuario.contacto }}
resultado email
204. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
205. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
{{ usuario[contacto] }}
resultado ERROR
206. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
207. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
{{ usuario[usuario.contacto] }}
resultado ..@..
208. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
209. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
{{ attribute(usuario, usuario.contacto) }}
210. {% set usuarios = [
{ 'email': '..@..', 'contacto': 'email' },
{ 'movil': '9....', 'contacto': 'movil' }
] %}
{{ attribute(usuario, usuario.contacto) }}
resultado ..@..
214. {% extends usuario.tipo ~ '.html.twig' %}
{# usuario = {'tipo': 'admin'} #}
admin.html.twig
{# usuario = {'tipo': 'usuario'} #}
usuario.html.twig
218. {% extends [
'categoria_' ~ noticia.categoria ~ '.html.twig',
'seccion_' ~ noticia.seccion ~ '.html.twig',
'noticia.html.twig'
] %}
221. {% include [
'lateral_' ~ noticia.categoria ~ '.html.twig',
'lateral_' ~ noticia.seccion ~ '.html.twig',
'lateral.html.twig'
] %}
222. {% set seccion = ... %}
{% include
'lateral_' ~ seccion ~ '.html.twig'
%}
223. 1.2
{% set seccion = ... %}
{% include
'lateral_' ~ seccion ~ '.html.twig'
ignore missing
%}
224. {% include '...' ignore missing %}
{% include '...' ignore missing
with { ... } %}
{% include '...' ignore missing
with { ... } only %}
228. copyright
Los contenidos de esta
presentación son propiedad
de su autor. No se pueden
reutilizar sin el consentimiento
expreso de su autor.