twig avanzado (sf2vigo)

228
Javier Eguiluz Twig avanzado Jornadas Symfony2 Galicia 25-26 noviembre 2011 #sf2Vigo

Upload: javier-eguiluz

Post on 15-Jan-2015

14.240 views

Category:

Technology


11 download

DESCRIPTION

Buenas prácticas, trucos, snipets y buenos usos del sistema de plantillas Twig, tanto dentro de Symfony2 como en proyectos PHP independientes

TRANSCRIPT

Javier Eguiluz

Twig avanzado

Jornadas Symfony2 Galicia25-26 noviembre 2011 #sf2Vigo

• Javier Eguiluz

• formador en Symfony2 y nuevas tecnologías

me presento

creador de http://symfony.es

apasionado de Symfony

http://connect.sensiolabs.com/profile/javier.eguiluz

• Buenas prácticas

• Trucos

• Usos avanzados

• Snipets

objetivos de la sesión

Si no sabes Twig, te vas a

perder a partir de la

siguiente transparencia

Aprende Twig en 5 minutos

«Twig es un lenguaje y motor de plantillas PHP»

twig se puede usar en

Symfony2 Cualquier proyecto PHP

¿Por qué usar Twig?

$usuario

public function getNombre(){ return $this->nombre;}

TWIG

{{ usuario.nombre }}

echo $usuario->getNombre()

PHP

<?phpecho $usuario->getNombre();?>

PHP

<?phpecho htmlspecialchars( $usuario->getNombre(), ENT_QUOTES, 'UTF-8');?>

PHP

TWIG

PHP

{{ usuario.nombre }}

<?php echo htmlspecialchars($usuario-> getNombre(), ENT_QUOTES, 'UTF-8'); ?>

Mostrarinformación

{# ... #}

{% ... %}

{{ ... }}

<p> Hola {{ usuario }}

Tienes {{ edad }} años y

vives en {{ ciudad }} </p>

<p> Hola {{ usuario.nombre }}

Tienes {{ usuario.edad }}

años y vives en

{{ usuario.ciudad }} </p>

{{ usuario.nombre }}

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

{{ usuario.nombre }}

<?php

abstract class Twig_Template implements Twig_TemplateInterface{

// ...

protected function getAttribute( $object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false) { // ... }}

Template.php

twig-ext

Derick Rethans

http://github.com/derickr/twig-ext

Modificar información

{{ descripcion }}

{{ descripcion | striptags }}

{{ titular | striptags | upper }}

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

{{ biografia }}

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

{{ biografia | raw }}

Espacios en blanco

<ul> <li> <a ... >XXX</a> </li>

<li> ...

{% spaceless %}

{% spaceless %}<ul> <li> <a ... >XXX</a> </li>

<li> ...{% endspaceless %}

<ul><li><a ... >XXX</a></li><li>...

Estructuras de control

{% for elemento in coleccion %} {# ... #}

{% endfor %}

{% for clave, elemento in coleccion %} {# ... #}

{% endfor %}

{% if condicion1 %}

{# ... #}

{% elseif condicion2 %}

{# ... #}

{% else %}

{# ... #}

{% endif %}

Herencia de plantillas

PORTADA

CONTACTO

# TITULO #

# CONTENIDOS #

# L

ATER

AL

#

# TITULO #

# CONTENIDOS #

# L

ATER

AL

#

layout.twig

<html> <head> ... </head>

<body>

<h1>

{% block titulo %}{% endblock %}

</h1>

{% block contenidos %}{% endblock %}

{% block lateral %}{% endblock %}

</body></html>

layout.twig

<html> <head> ... </head>

<body>

<h1>

PORTADA

</h1>

<div id="contenidos">...</div>

<div id="lateral">...</div>

</body></html>

portada.twig

<html> <head> ... </head>

<body>

<h1>

PORTADA

</h1>

<div id="contenidos">...</div>

<div id="lateral">...</div>

</body></html>

portada.twig

PORTADA

<div id="contenidos">...</div>

<div id="lateral">...</div>

portada.twig

{% extends "layout.twig" %}

PORTADA

<div id="contenidos">...</div>

<div id="lateral">...</div>

portada.twig

portada.twig{% extends "layout.twig" %}

{% block titulo %} PORTADA{% endblock %} {% block contenidos %} <div id="contenidos">...</div>{% endblock %}

{% block lateral %} <div id="lateral">...</div>{% endblock %}

contacto.twig{% extends "layout.twig" %}

{% block titulo %} CONTACTO{% endblock %} {% block contenidos %} <form>...</form>{% endblock %}

{% block lateral %} <p>...</p>{% endblock %}

ya pasaron los

5 minutos

Javier Eguiluz

DESARROLLOWEB ÁGIL CON

SYMFONY2

todos los ejemplos que se muestran

a continuación pertenecen al libro

Desarrollo web ágilcon Symfony2(disponible próximamente)

variablesglobales

# 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> &copy; 'now'|date('Y') - v.{{ version }}</footer>

# app/config/config.ymltwig: # ... globals: cp: 01001 iva: [1.04, 1.08, 1.18] version: 1.0.3

# 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> &copy; 'now'|date('Y') - v.{{ global.version }}</footer>

# app/config/config.ymltwig: # ... globals: global: cp: 01001 iva: [1.04, 1.08, 1.18] version: 1.0.3

namespace Cupon\OfertaBundle\Util;

class Util{ static public function getSlug($cadena) { // ... return $slug; }}

servicios como variables globales

# app/config/config.yml

services:

# ...

cupon.utilidades:

class: Cupon\OfertaBundle\Util\Util

# app/config/config.yml

twig:

# ...

globals:

utilidades: @cupon.utilidades

# app/config/config.yml

twig:

# ...

globals:

utilidades: @cupon.utilidades

{{ utilidades.getSlug('Lorem ipsum dolor sit amet') }}

depurandovariables

<?php var_dump($oferta); ?>

{% debug oferta %}

# app/config/config.yml

services:

twig.extension.debug:

class: Twig_Extensions_Extension_Debug

tags:

- { name: twig.extension }

for ... else

{% for articulo in articulos %}

{{ articulo.titulo }}

{# ... #}

{% endfor %}

{% for articulo in articulos %}

{{ articulo.titulo }}

{# ... #}

{% else %}

No hay artículos

{% endfor %}

for ... if

Itera sólamente por las ofertas baratas

{% for oferta in ofertas if oferta.precio < 10 %} {# ... #}

{% endfor %}

{% for elemento in coleccion if condicion %} {# ... #}

{% endfor %}

1.2

Itera sólamente por los amigos del usuario

{% set usuarios = 1..30 %}

{% set amigos = [12, 29, 34, 55, 67] %}

{% 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 %}

Operadoresde división

{{ 12 / 7 }}

{{ 12 // 7 }}

{{ 12 % 7 }}

1.7142857142

1

5

resultadooperación

creandovariables

{% set nombre = 'José García' %}

{% set edad = 27 %}{% set precio = 104.83 %}

{% set conectado = false %}

{% set tasaImpuestos = [4, 8, 18] %}

{% set perfil = {

'nombre': 'José García',

'perfiles': ['usuario', 'admin'],

'edad': 27,

'validado': true

} %}

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

{% set experiencia = edad ~ ' años' %}

{% set perfil %} Nombre: {{ usuario.nombre }} Apellidos: {{ usuario.apellidos }} Edad: {{ usuario.edad }} años Página: {{ usuario.url }}

{% endset %}

{{ perfil }}

{% set nombre, edad, activado = 'José', 27, false %}

{{ nombre }}{{ edad }}{% if activado %}

espaciosen blanco

class DefaultController extends Controller{ {% if comentarios %} /** * Primera línea * Segunda línea */ {% endif %}

class DefaultController extends Controller{ /** * Primera línea * Segunda línea */

NO

SI

class DefaultController extends Controller{ /** * Primera línea * Segunda línea */

SI

class DefaultController extends Controller{ /** * Primera línea * Segunda línea */

class DefaultController extends Controller{ {% if comentarios %} /** * Primera línea * Segunda línea */ {% endif %}

class DefaultController extends Controller{ {% if comentarios %} /** * Primera línea * Segunda línea */ {% endif %}

class DefaultController extends Controller{{% if comentarios %} /** * Primera línea * Segunda línea */{% endif %}

class DefaultController extends Controller{ /** * Primera línea * Segunda línea */

SI

class DefaultController extends Controller{ {% if comentarios %} /** * Primera línea * Segunda línea */ {% endif %}

class DefaultController extends Controller{ {% if comentarios -%} /** * Primera línea * Segunda línea */ {%- endif %}

class DefaultController extends Controller{ /** * Primera línea * Segunda línea */

SI

{% if condicion -%} {# ... #}

{%- endif %}

class DefaultController extends Controller{ {% if comentarios -%} /** * Comentario */ {%- else -%} /** * @Anotacion(...) */ {%- endif %}

formatearinformación

{{ '%.0f'|format(time * 1000) }} ms

{{ '%.0f'|format(time * 1000) }} ms

{{ '%.0f'|format(time * 1000) }} ms

{{ '%0.2f'|format(time * 1000) }} ms

{{ '%.0f'|format(time * 1000) }} ms

macrospolimórficas

{# formulario.html.twig #}

{% macro campo(nombre, tipo, valor) %}

<input type="{{ tipo }}"

name="{{ nombre }}"

value="{{ valor }}" />

{% endmacro %}

{% from 'formularios.html.twig'

import campo as campo %}

{% from 'formularios.html.twig'

import campo as campo %}

<table>

{{ campo('nombre', 'text', 'José') }}

{{ campo('apellidos', 'text', 'García Pérez') }}

{{ campo('telefono', 'text') }}

</table>

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

{# formulario.html.twig #}

{% macro campo(nombre, tipo, valor) %}

<input type="{{ tipo }}" name="{{ nombre }}"

value="{{ valor }}" />

{% endmacro %}

{# 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 %}

{# formulario.html.twig #}

{% macro campo(nombre, tipo, valor) %}

<input type="{{ tipo }}" name="{{ nombre }}"

value="{{ valor }}" />

{% endmacro %}

{# 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 %}

{% from 'formularios.html.twig'

import campo as campo %}

{{ campo('nombre', 'text', 'José') }}

{{ campo('apellidos', 'text', 'García Pérez') }}

{{ campo('telefono', 'text') }}

{% from 'formularios.html.twig'

import fila as campo %}

<table>

{{ campo('nombre', 'text', 'José') }}

{{ campo('apellidos', 'text', 'García Pérez') }}

{{ campo('telefono', 'text') }}

</table>

{% from 'formularios.html.twig'

import item as campo %}

<ul>

{{ campo('nombre', 'text', 'José') }}

{{ campo('apellidos', 'text', 'García Pérez') }}

{{ campo('telefono', 'text') }}

</ul>

filtros dependientesdel entorno

public function getFilters(){ return array('longitud' => new \Twig_Filter_Method($this, 'longitud') );}

function longitud($valor){ return strlen($valor);}

public function getFilters(){ return array('longitud' => new \Twig_Filter_Method($this, 'longitud') );}

function longitud($valor){ return strlen($valor);}

エラーが発生

function longitud($valor){ return mb_strlen($valor, 'EUC-JP');}

public function getFilters()

{

return array(

'longitud' => new \Twig_Filter_Method(

$this,

'longitud',

array('needs_environment' => true)

)

);

}

public function getFilters()

{

return array(

'longitud' => new \Twig_Filter_Method(

$this,

'longitud',

array('needs_environment' => true)

)

);

}

function longitud(\Twig_Environment $entorno, $valor)

{

$codificacion = $entorno->getCharset();

return mb_strlen($valor, $codificacion);

}

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);

// ...}

notaciónbundle

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

MiBundle/

Resources/

views/

src/MiAplicacion/

Carpeta/

plantilla.html.twig

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:Subcarpeta/ plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:Subcarpeta/ plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:Subcarpeta1/ Subcarpeta2/plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include'MiBundle::Carpeta/plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include 'MiBundle:Carpeta:plantilla.html.twig' %}

{% include'views/Carpeta/plantilla.html.twig' %}

opciones de configuración

# app/config/config.yml

twig:

autoescape: true

auto_reload: ~

cache: %kernel.cache_dir%/twig

charset: %kernel.charset%

debug: %kernel.debug%

strict_variables: ~

$twig = new Twig_Environment($loader, array(

'debug' => true,

'strict_variables' => true,

'charset' => 'UTF-8',

'cache' => __DIR__.'/cache'

));

# 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) { // ... }

# 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) { // ... }

# app/config/config.yml

twig:

# ...

exception_controller: Symfony\Bundle\TwigBundle

\Controller\ExceptionController::showAction

# app/config/config.yml

twig:

# ...

form:

resources: [ ... ]

formulariospersonalizados

modificar campos de una plantilla

{{ form_row(noticia.url) }}

modificar campos de una plantilla

{{ form_row(noticia.url) }}

Label

modificar campos de una plantilla

{% block url_widget %}{% spaceless %} {% set type = type|default('url') %} {{ block('field_widget') }}{% endspaceless %}{% endblock url_widget %}

{{ form_row(noticia.url) }}

Label

{{ form_row(noticia.url) }}

{% form_theme form _self %}

{% block url_widget %} {% set type = 'url' %} <em>http://</em> {{ block('field_widget') }}{% endblock url_widget %}

{{ form_row(noticia.url) }}

{% form_theme form _self %}

{% block url_widget %} {% set type = 'url' %} <em>http://</em> {{ block('field_widget') }}{% endblock url_widget %}

{{ 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://

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 %}

{% form_theme form 'MiBundle:Form:form.html.twig' %}

{{ form_row(noticia.titular) }}

{{ form_row(noticia.publicada) }}

{{ form_row(noticia.url) }}

# app/config/config.yml

twig:

# ...

form:

resources: - 'form_div_layout.html.twig'

modificar todos los formularios

# app/config/config.yml

twig:

# ...

form:

resources: - 'form_table_layout.html.twig'

{% 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 %}

{# ... #}

{% use "form_div_layout.html.twig" %}

{% block field_row %} {# ... #}{% endblock %}

{% block form_errors %} {# ... #}{% endblock %}

{% block hidden_row %} {# ... #}{% endblock %}

{% block form_widget %} {# ... #}{% endblock %}

# app/config/config.yml

twig:

# ...

form:

resources: - 'MiBundle:Form:form.html.twig'

mostrandocampos de fecha

{{ form_row(fecha) }}

{{ form_label(fecha) }}

{{ form_errors(fecha) }}

{{ form_widget(fecha) }}

{{ form_label(fecha) }}

{{ form_errors(fecha) }}

{{ form_widget(fecha.year) }}

{{ form_widget(fecha.month) }}

{{ form_widget(fecha.day) }}

generandocódigo

«Twig genera con facilidad cualquier tipo

de contenido»

public function indexAction()

{

$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 %}

}

Symfony2

/* 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 { /* ... */ }

easybook3

{% block NamespaceDeclaration %}{% if namespace %}namespace {{ namespace }};

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 %}}

Doctrine2ActiveRecord

https://github.com/

cedriclombardot/

TwigGenerator

twig.js

<select id="ciudad"> {% for ciudad in ciudades %} <option value="{{ ciudad.slug }}"> {{ ciudad.nombre }} </option> {% endfor %}</select>

<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>

<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>

<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>

<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>

https://github.com/

FriendsOfSymfony/

FOSJsRoutingBundle

{% twig_js name="perfil" %}

Nombre: {{ nombre }}

Apellidos: {{ apellidos }}

{% twig_js name="perfil" %}

Nombre: {{ nombre }}

Apellidos: {{ apellidos }}

<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>

https://github.com/

schmittjoh/

twig.js

flexible

Tienes {{ amigos|length }} amigos

y tu nombre tiene

{{ nombre|length }} letras

{{ ... | length }}

Tienes {{ amigos|length }} amigos

y tu nombre tiene

{{ nombre|length }} letras

{{ ... | length }}

count( )

Tienes {{ amigos|length }} amigos

y tu nombre tiene

{{ nombre|length }} letras

{{ ... | length }}

count( )

strlen( )

{% 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 %}

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

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

{{ ... in ... }}

in_array( )

strpos( )

{% for letra in 'a'|upper..inicial|default('z')|upper %}

{{ letra }}

{% endfor %}

{% 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'|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 %}

propiedadesvariables

{{ objeto.propiedad }}

{{ objeto.propiedad }}

{% set bundles = {

'AsseticBundle' => '.../vendor/...',

'BackendBundle' => '.../src/...',

'CiudadBundle' => '.../src/...',

'DoctrineBundle' => '.../vendor/...',

...

} %}

{{ bundles.'AsseticBundle' }}

NO

{% set nombre = 'AsseticBundle' %}

{{ bundles[nombre] }}

SI

{% for name in bundles|keys|sort %}

<tr>

<th>{{ name }}</th>

<td>{{ bundles[name] }}</td>

</tr>

{% endfor %}

{% set usuarios = [

{ 'email': '..@..' },

{ 'movil': '9....' }

] %}

{% set usuarios = [

{ 'email': '..@..' },

{ 'movil': '9....' }

] %}

{% for usuario in usuarios %}

{{ usuario.nombre }}

Contacto {{ usuario.????? }}

{% endfor %}

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{{ usuario.contacto }}

emailresultado

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{{ usuario[contacto] }}

ERRORresultado

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{{ usuario[usuario.contacto] }}

[email protected]

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{{ attribute(usuario, usuario.contacto) }}

{% set usuarios = [

{ 'email': '..@..', 'contacto': 'email' },

{ 'movil': '9....', 'contacto': 'movil' }

] %}

{{ attribute(usuario, usuario.contacto) }}

[email protected]

1.2

{{ attribute(objeto, propiedad) }}

{{ attribute(objeto, expresion) }}

{{ attribute(producto, 'foto' ~ i) }}

1.2

{{ attribute(objeto, metodo,

argumentos) }}

{{ attribute(objeto, metodo) }}

herenciadinámica

{% extends usuario.tipo ~ '.html.twig' %}

{# usuario = {'tipo': 'admin'} #}admin.html.twig

{# usuario = {'tipo': 'usuario'} #}usuario.html.twig

{% extends listado ? 'listado.html.twig' : 'tabla.html.twig' %}

{% extends ['primera.html.twig',

'segunda.html.twig',

'tercera.html.twig'] %}

1.2

{% extends 'noticia.html.twig' %}

{% extends [

'categoria_' ~ noticia.categoria ~ '.html.twig',

'seccion_' ~ noticia.seccion ~ '.html.twig',

'noticia.html.twig'

] %}

includedinámico

{% include ['primera.html.twig',

'segunda.html.twig',

'tercera.html.twig'] %}

1.2

{% include [

'lateral_' ~ noticia.categoria ~ '.html.twig',

'lateral_' ~ noticia.seccion ~ '.html.twig',

'lateral.html.twig'

] %}

{% set seccion = ... %}

{% include

'lateral_' ~ seccion ~ '.html.twig'

%}

{% set seccion = ... %}

{% include

'lateral_' ~ seccion ~ '.html.twig'

ignore missing

%}

1.2

{% include '...' ignore missing %}

{% include '...' ignore missing

with { ... } %}

{% include '...' ignore missing

with { ... } only %}

muchas gracias

dudas preguntas comentarios

linkedin.com/in/javiereguiluz

contacta

conecta

[email protected]

copyrightLos contenidos de esta presentación son propiedad de su autor. No se pueden reutilizar sin el consentimiento expreso de su autor.