• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Twig, los mejores trucos y técnicas avanzadas
 

Twig, los mejores trucos y técnicas avanzadas

on

  • 10,049 views

 

Statistics

Views

Total Views
10,049
Views on SlideShare
4,234
Embed Views
5,815

Actions

Likes
9
Downloads
187
Comments
0

27 Embeds 5,815

http://www.symfony.es 3428
http://desymfony.com 1044
http://blog.liip.ch 719
https://blog.liip.ch 228
http://www.desymfony.com 129
http://symfony.es 106
http://desymfony.es 48
http://librosweb.es 21
http://www.aggregator.ch 15
http://symfony.local 11
http://desymfony.local 10
http://www.desymfony.es 7
http://www.newsblur.com 7
http://translate.googleusercontent.com 7
http://desymfony.eu 6
http://192.168.11.11 6
http://www.sfexception.com 5
http://amphibiology1.rssing.com 4
http://reader.feedshow.com 3
http://192.168.11.10 3
http://news.php-homepage.de 2
http://diysdk.schlund.de 1
http://planet.freeflux.net 1
http://desymfony.acilia.es 1
http://ranksit.com 1
http://feeds.liip.ch 1
http://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Twig, los mejores trucos y técnicas avanzadas Twig, los mejores trucos y técnicas avanzadas Presentation Transcript

    • Twig, los mejores trucos ytécnicas avanzadasJavier EguíluzUniversitat Jaume I · Castellón · 15-16 junio 2012 · desymfony.com
    • ¡muchas gracias a nuestros patrocinadores! PATROCINADOR PLATINOPATROCINADORES OROPATROCINADORES PLATAPATROCINADORES BRONCE
    • Agenda • Buenas prácticas • Técnicas avanzadas • Trucos y cosas nuevas
    • CódigoEl código fuente de los ejemplosmás avanzados de esta ponenciaestá disponible en:https://github.com/javiereguiluz/desymfony!twig
    • PERSONALIZACIÓN EXTREMA DE FORMULARIOS1.* BÁSICO INTERMEDIO AVANZADO
    • <div> {{ form_label(form.nombre) }} {{ form_errors(form.nombre) }} {{ form_widget(form.nombre) }}</div>
    • {% extends ::base.html.twig %}{% form_theme form _self %}{% block integer_widget %} <div class="integer_widget"> {% set type = type|default(number) %} {{ block(field_widget) }} </div>{% endblock %}{% block content %} {# render the form #} {{ form_row(form.age) }}{% endblock %}
    • {% extends ::base.html.twig %}{% form_theme form _self %}{% block integer_widget %} <div class="integer_widget"> {% set type = type|default(number) %} {{ block(field_widget) }} </div>{% endblock %}{% block content %} {# render the form #} {{ form_row(form.age) }}{% endblock %}
    • {% extends ::base.html.twig %}{% form_theme form _self %}{% block integer_widget %} <div class="integer_widget"> {% set type = type|default(number) %} {{ block(field_widget) }} </div>{% endblock %}{% block content %} {# render the form #} {{ form_row(form.age) }}{% endblock %}
    • {% form_theme form _self %}{% block _formulario_nombre_widget %} <div class="especial"><strong> {{ block(field_widget) }} </strong></div>{% endblock %}{{ form_widget(form.nombre) }}
    • {% form_theme form _self %}{% block _formulario_nombre_widget %} <div class="especial"><strong> {{ block(field_widget) }} </strong></div>{% endblock %}{{ form_widget(form.nombre) }}
    • class UsuarioType extends AbstractType{ public function buildForm(FormBuilder $builder, array $options) { $builder ->add(nombre) ->add(apellidos) ->add(email) ->... ->add(ciudad) ; } public function getName() { return cupon_backendbundle_usuariotype; }}
    • class UsuarioType extends AbstractType{ public function buildForm(FormBuilder $builder, array $options) { $builder ->add(nombre) ->add(apellidos) ->add(email) ->... ->add(ciudad) ; } public function getName() { return cupon_backendbundle_usuariotype; }}
    • <strong>Label</strong>: Valor
    • <strong>Label</strong>: Valor<strong>{{ form.nombreCampo.vars.label }}</strong>:{{ form. nombreCampo.vars.value }}
    • <strong>Label</strong>: Valor<strong>{{ form.nombreCampo.vars.label }}</strong>:{{ form. nombreCampo.vars.value }}
    • CONSTANTES1.* BÁSICO INTERMEDIO AVANZADO
    • {{ constant() }}
    • {{ constant(SymfonyComponentHttpKernelKernel::VERSION) }}
    • {{ constant(SymfonyComponentHttpKernelKernel::VERSION) }}namespace SymfonyComponentHttpKernel;abstract class Kernel implements KernelInterface{ // ... const VERSION = 2.0.15;}
    • namespace SymfonyComponentHttpKernel;abstract class Kernel implements KernelInterface{ // ... const VERSION = 2.1.0-DEV; const VERSION_ID = 20100; const MAJOR_VERSION = 2; const MINOR_VERSION = 1; const RELEASE_VERSION = 0; const EXTRA_VERSION = DEV;}
    • REDEFINE LOS FILTROS POR DEFECTO1.* BÁSICO INTERMEDIO AVANZADO
    • {{ array|sort }}
    • asort() array_multisort()arsort() natcasesort()krsort() natsort()ksort() rsort()rsort() shuffle()shuffle() uasort()sort() uksort()usort()
    • ¿Dónde se definenlos filtros, etiquetas y tags de Twig?
    • lib/twig/Extesion/Core.phpclass Twig_Extension_Core extends Twig_Extension { public function getTokenParsers() { return array( new Twig_TokenParser_For(), new Twig_TokenParser_If(), new Twig_TokenParser_Extends(), new Twig_TokenParser_Include(), new Twig_TokenParser_Block(), // ... ); } public function getFilters() { $filters = array( format => new Twig_Filter_Function(sprintf), replace => new Twig_Filter_Function(strtr), abs => new Twig_Filter_Function(abs),
    • {{ array|sort }}/** * Sorts an array. * * @param array $array An array */function twig_sort_filter($array){ asort($array); return $array;}
    • natcasesort()a0, A1, a2, a10, ...
    • class MiCoreExtension extends Twig_Extension_Core { // ...}
    • class MiCoreExtension extends Twig_Extension_Core { public function getFilters() { // ... }}
    • class MiCoreExtension extends Twig_Extension_Core { public function getFilters() { return array_merge( parent::getFilters(), array( ... ) ); }}
    • $twig = new Twig_Environment($loader, array( ... ));$twig->addExtension(new MiCoreExtension());
    • class MiCoreExtension extends Twig_Extension_Core{ public function getFilters() { return array_merge(parent::getFilters(), array( sort => new Twig_Filter_Method($this, sortFilter) )); } public function sortFilter($array) { natcasesort($array); return $array; }}
    • {{ array|sort }}function twig_sort_filter($array){ natcasesort($array); return $array;}
    • TODO SON EXPRESIONES1.5 BÁSICO INTERMEDIO AVANZADO
    • {% include seccion_ ~ oferta.categoria ~ .twig %}{% for i in (1+3)//2..2**(3-1) %}{% endfor %}
    • {% set ofertas = { (oferta ~ oferta.id): ..., (3 ~ _ ~ oferta.nombre|length): ..., (2**2+1): ...} %}
    • {% set ofertas = { (oferta ~ oferta.id): ..., (3 ~ _ ~ oferta.nombre|length): ..., (2**2+1): ...} %}
    • {% set ofertas = { oferta7040: ..., 3_57: ..., 5: ...} %}
    • EMBED1.8 BÁSICO INTERMEDIO AVANZADO
    • {% include %} {% extends %} {% embed %}
    • {% include ... %}
    • {% extends ... %}
    • {% embed ... %}
    • {% embed "lateral.twig" %} {% block principal %} ... {% endblock %}{% endembed %}
    • {% embed "lateral.twig" %} {% block secundario %} ... {% endblock %}{% endembed %}
    • {% include plantilla.twig %}{% embed plantilla.twig %}{% endembed %}
    • ESCAPING AUTOMÁTICO1.8 BÁSICO INTERMEDIO AVANZADO
    • {% filter escape(js) %} <script type="text/javascript"> var texto = "<p>Lorem ipsum dolor sit amet</p>"; alert(texto); </script>{% endfilter %}{% filter escape(html) %} <script type="text/javascript"> var texto = "<p>Lorem ipsum dolor sit amet</p>"; alert(texto); </script>{% endfilter %}
    • x3cscript typex3dx22textx2fjavascriptx22x3ex0avar texto x3d x22x3cpx3eLorem ipsum dolor sit ametx3cx2fpx3ex22x3bx0a alertx28textox29x3bx0ax3cx2fscriptx3ex0a&lt;script type=&quot;text/javascript&quot;&gt; var texto = &quot;&lt;p&gt;Lorem ipsum dolor sit amet&lt;/p&gt;&quot;; alert(texto);&lt;/script&gt;
    • {{ variable|e }}{{ variable|e(html) }}{{ variable|escape(js) }}{{ variable|e(js) }}{% autoescape %} ........... {% endautoescape %}{% autoescape html %} ... {% endautoescape %}{% autoescape js %} ....... {% endautoescape %}{% autoescape false %} .... {% endautoescape %}
    • $twig = new Twig_Environment($loader, array( autoescape => function($nombre_plantilla) { return decide_escape($nombre_plantilla); }));
    • $twig = new Twig_Environment($loader, array( autoescape => function($nombre_plantilla) { return decide_escape($nombre_plantilla); }));function decide_escape($plantilla) { $extension = substr($plantilla, strrpos($plantilla, .) + 1); switch ($extension) { js: return js; default: return html; }}
    • RANDOM1.6 BÁSICO INTERMEDIO AVANZADO
    • {{ random() }}
    • {{ random() }}{{ random(10) }}
    • {{ random() }}{{ random(10) }}{{ random("abcde") }}
    • {{ random() }}{{ random(10) }}{{ random("abcde") }}{{ random([a, b, c]) }}
    • FUNCIONES DINÁMICAS1.5 BÁSICO INTERMEDIO AVANZADO
    • the_ID()the_title()the_time()the_content()the_category()the_shortlink()
    • the_ID()the_title()the_time()the_content()the_category()the_shortlink()
    • the_ID()the_title()the_time()the_content()the_category()the_shortlink()the_*()
    • $twig->addFunction( the_*, new Twig_Function_Function(wordpress));function wordpress($funcion, $opciones){ // ...}
    • $twig->addFunction( the_*, new Twig_Function_Function(wordpress));function wordpress($funcion, $opciones){ // ...}
    • {{ the_ID() }}
    • {{ the_ID() }}function wordpress(ID, array()) { ... }
    • {{ the_ID() }}function wordpress(ID, array()) { ... }{{ the_content() }}
    • {{ the_ID() }}function wordpress(ID, array()) { ... }{{ the_content() }}function wordpress(content, array()){ ... }
    • {{ the_title(<h3>, </h3>) }}function wordpress(title, array( <h3>, </h3>)) { ... }
    • *_*_link()next_image_link()next_post_link()next_posts_link()previous_image_link()previous_post_link()previous_posts_link()
    • php_*()
    • FILTROS DINÁMICOS1.5 BÁSICO INTERMEDIO AVANZADO
    • {{ now|fecha_corta }}{{ now|fecha_larga }}fecha_*()
    • $twig->addFilter( fecha_*, new Twig_Filter_Function(fecha));function fecha($funcion, $opciones){ // ...}
    • VARIABLES GLOBALES1.* BÁSICO INTERMEDIO AVANZADO
    • {{ app.security }}{{ app.user }}{{ app.request }}{{ app.session }}{{ app.environment }}{{ app.debug }}
    • {{ _charset }}{{ _context }}{{ _self }}
    • {{ _charset }} UTF-8
    • {{ _context }}{% for i in _context|keys %} {{ i }}{% endfor %}
    • {{ _context }}{% for i in _context|keys %} {{ i }} app assetic{% endfor %} _parent oferta ciudad_por_defecto ciudadSeleccionada expirada ...
    • {{ _context }}{% for i in _context|keys %} {{ i }} app assetic{% endfor %} _parent oferta ciudad_por_defecto ciudadSeleccionada expirada ...
    • {{ _context }}{{ variable|mi_filtro(_context) }}
    • {{ _context }}{{ variable|mi_filtro(_context) }} SÓLO SI NO HAY OTRO REMEDIO
    • {{ _self }}Twig_Template
    • {{ _self }}{{ _self.getTemplateName }}OfertaBundle:Default:includes/oferta.html.twig
    • {{ _self }}{{ _self.blocks|keys|join(", ") }}title, stylesheets, rss, javascripts,id, body
    • {{ _self }}{{ _self.blocks|keys|join(", ") }}title, stylesheets, rss, javascripts,id, body SÓLO SI NO HAY OTRO REMEDIO
    • EL SANDBOX1.* BÁSICO INTERMEDIO AVANZADO
    • DEMO
    • DATE1.6 BÁSICO INTERMEDIO AVANZADO
    • {{ now|date("d/m/Y H:i:s") }}{{ now|date("d/m/Y H:i:s", "America/Argentina/Buenos_Aires") }}{{ now|date("d/m/Y H:i:s", "America/Havana") }}{{ now|date("d/m/Y H:i:s", "America/Caracas") }}{{ now|date("d/m/Y H:i:s", "America/Lima") }}
    • España: 11/06/2012 10:45:22Argentina: 11/06/2012 05:45:22Cuba: 11/06/2012 04:45:22Venezuela: 11/06/2012 04:15:22Perú: 11/06/2012 03:45:22
    • $twig = new Twig_Environment($loader);$twig->getExtension(core) ->setDateFormat(d-m-Y H:i:s, %d días);$twig->getExtension(core) ->setTimezone(America/Montevideo);
    • date()
    • {{ date() }}
    • {{ date() }}{{ date()|date() }}
    • {{ date() }}{{ date()|date() }}{{ date()|date("d/m/Y") }}
    • Tu invitación caduca el{{ date(+2days)|date }}
    • Tu invitación caduca el{{ date(+2days)|date }}{% if date(fechaNacimiento) < date(-18years) %} ¡Eres menor de edad!{% endif %}
    • La última sorpresa de#deSymfony se desvelará el{{ date(next Monday)|date() }}
    • OPERADORES PROPIOS1.* BÁSICO INTERMEDIO AVANZADO
    • $loader = new Twig_Loader_Filesystem(...);$twig = new Twig_Environment($loader, array(...));$twig->addExtension(new OperatorsExtension());
    • Operador "quédate con el mayor" {{ 5 >> 2 }} 5 {{ 4 >> 20 }} 20
    • class OperatorsExtension extends Twig_Extension{ public function getName() { return OperatorsExtension; } public function getOperators() { return array( array(), array(>> => array( precedence => 20, class => DesymfonyOperatorsMaxOperator, associativity => Twig_ExpressionParser::OPERATOR_LEFT ) )); }}
    • class OperatorsExtension extends Twig_Extension{ public function getName() { return OperatorsExtension; } public function getOperators() { return array( array(), array(>> => array( precedence => 20, class => DesymfonyOperatorsMaxOperator, associativity => Twig_ExpressionParser::OPERATOR_LEFT ) )); }}
    • class OperatorsExtension extends Twig_Extension{ public function getName() { return OperatorsExtension; } public function getOperators() { return array( array(), array(>> => array( precedence => 20, class => DesymfonyOperatorsMaxOperator, associativity => Twig_ExpressionParser::OPERATOR_LEFT ) )); }}
    • 2 +3**2 / 4 .. 4-5//2 Operador Precedence != 20 + 30 ** 200
    • {{ a >> b }} max($a, $b); TWIG PHP
    • class MaxOperator extends Twig_Node_Expression_Binary{ public function compile(Twig_Compiler $compiler) { $compiler ->raw(max() ->subcompile($this->getNode(left)) ->raw(, ) ->subcompile($this->getNode(right)) ->raw()) ; }
    • class MaxOperator extends Twig_Node_Expression_Binary{ public function compile(Twig_Compiler $compiler) { $compiler ->raw(max() ->subcompile($this->getNode(left)) ->raw(, ) ->subcompile($this->getNode(right)) ->raw()) ; } max($a, $b);
    • // line 23echo twig_escape_filter($this->env, max(5, 2), "html", null, true);
    • $compiler ->raw() (literal) ->write() (indentado) ->string() (entrecomillado) ->indent() (indentar) ->outdent() (desindentar);
    • Operador "cambia claves por valores" PHP array_flip(range(a, z))TWIG {% for i in <->(a..z) %} {{ i }}, {% endfor %}
    • Operador "cambia claves por valores" PHP array_flip(range(a, z))TWIG {% for i in <->(a..z) %} {{ i }}, {% endfor %}
    • class OperatorsExtension extends Twig_Extension{ public function getName() { return OperatorsExtension; } public function getOperators() { return array( array(<-> => array( precedence => 50, class => DesymfonyOperatorsFlipOperator, ), array() )); }}
    • class OperatorsExtension extends Twig_Extension{ public function getName() { return OperatorsExtension; } public function getOperators() { return array( array(<-> => array( precedence => 50, class => DesymfonyOperatorsFlipOperator, ), array() )); }}
    • class OperatorsExtension extends Twig_Extension{ public function getName() { return OperatorsExtension; } public function getOperators() { return array( array(<-> => array( precedence => 50, class => DesymfonyOperatorsFlipOperator, ), array() )); }}
    • namespace DesymfonyOperators;class FlipOperator extends Twig_Node_Expression_Unary{ public function compile(Twig_Compiler $compiler) { $compiler ->raw("array_flip(") ->subcompile($this->getNode(node)) ->raw(")") ; }
    • namespace DesymfonyOperators;class FlipOperator extends Twig_Node_Expression_Unary{ public function compile(Twig_Compiler $compiler) { $compiler ->raw("array_flip(") ->subcompile($this->getNode(node)) ->raw(")") ; } array_flip($coleccion);
    • // line 17$context[_parent] = (array) $context;$context[_seq] = twig_ensure_traversable(array_flip(range("a", "z")));foreach ($context[_seq] as $context["_key"] => $context["i"]) { // line 18 echo " "; if (isset($context["i"])) { $_i_ = $context["i"]; } else { $_i_ = null; } echo twig_escape_filter($this->env, $_i_, "html", null, true); echo ",";}
    • // line 17$context[_parent] = (array) $context;$context[_seq] = twig_ensure_traversable(array_flip(range("a", "z")));foreach ($context[_seq] as $context["_key"] => $context["i"]) { // line 18 echo " "; if (isset($context["i"])) { $_i_ = $context["i"]; } else { $_i_ = null; } echo twig_escape_filter($this->env, $_i_, "html", null, true); echo ",";}
    • SUPER CACHÉ1.* BÁSICO INTERMEDIO AVANZADO
    • # mkfs -q /dev/ram1 65536# mkdir -p /twigcache# mount /dev/ram1 /twigcacheInspirado por: http://www.cyberciti.biz/faq/howto!create!linux!ram!disk!filesystem/
    • $twig = new Twig_Environment( $loader, array(cache => /twigcache));# app/config/config.ymltwig: cache: /twigcache
    • ETIQUETAS PROPIAS1.* BÁSICO INTERMEDIO AVANZADO
    • etiquetasoperadores #1 tests #2 #3
    • {% source simple.twig %}{% source ../../../composer.json %}
    • 1. Clase Token Parser TWIG TWIG2. Clase Node TWIG PHP
    • $loader = new Twig_Loader_Filesystem(...);$twig = new Twig_Environment($loader, array(...));$twig->addTokenParser(new SourceTokenParser());
    • {% source ... %}class SourceTokenParser extends Twig_TokenParser{ public function getTag() { return source; }}
    • namespace DesymfonyTags;use DesymfonyTagsSourceNode;class SourceTokenParser extends Twig_TokenParser{ public function parse(Twig_Token $token) { $lineno = $token->getLine(); $value = $this->parser->getExpressionParser()->parseExpression(); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); return new SourceNode($value, $lineno, $this->getTag()); }}
    • class SourceNode extends Twig_Node{ public function __construct(Twig_Node_Expression $value, $lineno, $tag = null) { parent::__construct(array(file => $value), array(), $lineno, $tag); } public function compile(Twig_Compiler $compiler) { $compiler -> // ... ->write(echo file_get_contents() ->subcompile($this->getNode(file)) ->raw();); ; }}
    • // line 3echo file_get_contents("simple.twig");// line 4echo "n";// line 5echo file_get_contents("../../../composer.json");// line 6echo "n";
    • INTERPOLACIÓN1.5 BÁSICO INTERMEDIO AVANZADO
    • La oferta cuesta 25.78 euros(30.42 con IVA) y es válidahasta el 10/06/2012
    • La oferta cuesta 25.78 euros(30.42 con IVA) y es válidahasta el 10/06/2012
    • La oferta cuesta 25.78 euros (30.42 con IVA) y esválida hasta el 10/06/2012 ~{{ La oferta cuesta ~ oferta.precio ~ euros ( ~oferta.precio*1.18 ~ con IVA) y es válida hasta el ~oferta.fechaExpiracion|date() }}
    • La oferta cuesta 25.78 euros (30.42 con IVA) y esválida hasta el 10/06/2012 format(){{ La oferta cuesta %.2f euros (%.2f con IVA) y esválida hasta el %s|format(oferta.precio,oferta.precio*1.18, oferta.fechaExpiracion|date()) }}
    • La oferta cuesta 25.78 euros (30.42 con IVA) y esválida hasta el 10/06/2012 replace(){{ La oferta cuesta :precio euros (:total con IVA) y esválida hasta el :fecha|replace({ :precio:oferta.precio, :total: oferta.precio*1.18, :fecha:oferta.fechaExpiracion|date() }) }}
    • La oferta cuesta 25.78 euros (30.42 con IVA) y esválida hasta el 10/06/2012{{ "La oferta cuesta #{oferta.precio}euros (#{oferta.precio*1.18} con IVA)y es válida hasta el#{oferta.fechaExpiracion|date()}" }}
    • {{ "... #{ expresión } ..." }}
    • {{ "... #{ expresión } ..." }}
    • NUEVOS FILTROS Y ETIQUETAS1.5 BÁSICO INTERMEDIO AVANZADO
    • {% flush %}
    • {% do %}
    • {{ 1 + 1 }} 2{% do 1 + 1 %} (nada)
    • {% set lista = [a, b, c, d] %}{{ lista|shift }}{% do lista|shift %}Fuente: https://github.com/fabpot/Twig/issues/446
    • [:]
    • {% set lista = [a, b, c, d] %} {{ lista[1:] }}
    • {% set lista = [a, b, c, d] %} {{ lista[-1:] }}
    • {% set lista = [a, b, c, d] %} {{ lista[2:2] }}
    • {{ @username[1:] }}{{ Lorem ipsum...[-4:10] }}
    • operadores bitwise{{ a b-and b }} $a ^ $b{{ a b-xor b }} $a << $b{{ a b-or b }} $a >> $b TWIG PHP
    • TWIG_TEMPLATE1.* BÁSICO INTERMEDIO AVANZADO
    • <html> <head> ... </head> <body> ... <span data-host="Darwin mbp.local 10.8.0 Darwin Kernel Version10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386" data-elapsed="0.97804594039917 sec."data-timestamp="1339609672.9781"></span> </body></html>
    • app/cache/dev/twig/
    • app/cache/dev/twig/
    • app/cache/dev/twig/09/fc/2d8a188dda8245d295e6324582f2.php<?php/* ::frontend.html.twig */class __TwigTemplate_09fc2d8a188dda8245d295e6324582f2extends Twig_Template{ public function __construct(Twig_Environment $env) { parent::__construct($env); $this->parent = $this->env->loadTemplate("::base.html.twig"); $this->blocks = array( stylesheets => array($this, block_stylesheets), javascripts => array($this, block_javascripts), body => array($this, block_body), article => array($this, block_article),
    • class __TwigTemplate_09f...2f2 extends Twig_Template{ // ...}
    • namespace CuponBackendBundleController;use SymfonyBundleFrameworkBundleControllerController;class UsuarioController extends Controller{ public function indexAction() { //... return $this->render( BackendBundle:Usuario:index.html.twig, array( ... ) ); }}
    • Symfony/Bundle/FrameworkBundle/Controller/Controller.phpfunction render($view, $parameters, $response) { return $this->container->get(templating) ->renderResponse($view, $parameters, $response);}
    • lib/Twig/Environment.phppublic function render($name, array $context = array()){ return $this->loadTemplate($name) ->render($context);}
    • return $this->render( ... );render( ... ) Twig_Template
    • return $this->render( ... );render( ... ) Twig_Template
    • <html> <head> ... </head> <body> ... <span data-host="Darwin mbp.local 10.8.0 Darwin Kernel Version10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386" data-elapsed="0.97804594039917 sec."data-timestamp="1339609672.9781"></span> </body></html>
    • base_template_class$loader = new Twig_Loader_Filesystem(__DIR__./../Resources/views);$twig = new Twig_Environment($loader, array( base_template_class => DesymfonyTemplateMiTwigTemplate,));# app/config/config.ymltwig: base_template_class: "DesymfonyTemplateMiTwigTemplate"
    • namespace DesymfonyTemplate;abstract class MiTwigTemplate extends Twig_Template{ public function render(array $context) { $traza = sprintf(<span data-host="%s" data-elapsed="%s sec." data-timestamp="%s"></span>, php_uname(), microtime(true)-$_SERVER[REQUEST_TIME], microtime(true) ); return str_replace(</body>, $traza."n</body>", parent::render($context) ); }}
    • TWIG LINTER1.* BÁSICO INTERMEDIO AVANZADO
    • $twig = new Twig_Environment($loader, array(..));try { $twig->parse($twig->tokenize($plantilla)); echo "[OK] La sintaxis de la plantilla es correcta";} catch (Twig_Error_Syntax $e) { echo "[ERROR] La plantilla tiene errores de sintaxis";}
    • $ php app/console twig:lint @MyBundle$ php app/console twig:lint src/Cupon/OfertaBundle/Resources/views/index.html.twig
    • twig:lint
    • twig:lintSYMFONY 2.1
    • twig:lint SYMFONY 2.1DESYMFONY 2013
    • ¡muchas gracias!
    • Contacto • javier.eguiluz@gmail.com • github.com/javiereguiluz • twitter.com/javiereguiluz • linkd.in/javiereguiluz