Top Banner
TWIG Tips & Tricks
34

Twig Brief, Tips&Tricks

Jul 18, 2015

Download

Technology

Andrei Burian
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Twig Brief, Tips&Tricks

TWIGTips & Tricks

Page 2: Twig Brief, Tips&Tricks

STRUCTURE AND

INTERNAL REPRESENTATION

Page 3: Twig Brief, Tips&Tricks

Twig's three tagsTwig parses just three simple tags:

{# comment tag - aren't rendered and they are also multi-line#} – do nothing!

{{ 'print tag' }} – say something!

{% set this = 'block tag' %} - do something!

Page 4: Twig Brief, Tips&Tricks
Page 5: Twig Brief, Tips&Tricks
Page 6: Twig Brief, Tips&Tricks

The LexerThe lexer tokenizes a template source code into a token stream. The default

lexer recognizes 13 different token types.

Here is the output for the Hello {{ name }} template:

TEXT_TYPE(Hello )VAR_START_TYPE()NAME_TYPE(name)VAR_END_TYPE()EOF_TYPE()

Page 7: Twig Brief, Tips&Tricks

The ParserThe parser converts the token stream into an AST (Abstract Syntax Tree), or

a node tree. The core extension defines the basic nodes like: for, if, ... and the expression nodes.

Here is the output for the Hello {{ name }} template:

Twig_Node_Module( Twig_Node_Text(Hello ) Twig_Node_Print( Twig_Node_Expression_Name(name) ))

Page 8: Twig Brief, Tips&Tricks

Templates’ sourcesapp/cache/prod/templates.php :

<?php return array ('::base.html.twig' => '<project_path>/app/Resources/views/base.html.twig','::header.html.twig' => '<project_path>/app/Resources/views/header.html.twig','::footer.html.twig' => '<project_path>/app/Resources/views/footer.html.twig','CrfMainBundle:Homepage:homepage.html.twig' => '<project_path>/src/Crf/MainBundle/Resources/views/Homepage/homepage.html.twig',

…);

Page 9: Twig Brief, Tips&Tricks

The CompilerThe last step is done by the compiler. It takes a node tree as an input and

generates PHP code usable for runtime execution of the template.

The generated template for a Hello {{ name }} template reads as follows:

/* Hello {{ name }} */class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template{ protected function doDisplay(array $context, array $blocks = array()) { // line 1 echo "Hello "; echo twig_escape_filter($this->env, $this->getContext($context, "name"), "html", null, true); }

// some more code}

Page 10: Twig Brief, Tips&Tricks
Page 11: Twig Brief, Tips&Tricks
Page 12: Twig Brief, Tips&Tricks

FUNCTIONALITIES AND

USAGE

Page 13: Twig Brief, Tips&Tricks

FOR Loops{% for user in users %}

{{user.name}}{% else %}

{{ ‘No users’ }}{% endfor %}

{% for i in 0..10 %}{% for l in 'a'..'z' %}{% for l in 'a'|upper..'z'|upper %}{% for i in 0|range(10, 2) %}

{% for blog in blogs %} <div class="link {{ cycle(['even', 'odd'], loop.index0) }}">

{{ blog.description }}</div> {% endfor %}

Page 14: Twig Brief, Tips&Tricks

IF TagMultiple branches:

{% if kenny.sick %} Kenny is sick.{% elseif kenny.dead %} You killed Kenny! You bastard!!!{% else %} Kenny looks okay --- so far{% endif %}

Ternary operator:

{{ human.alive ? ‘It’s alive’ : ‘Wasted’ }}

Page 15: Twig Brief, Tips&Tricks

- define a macro in a separate twig file:

- include your reusable macro where you want:

MACROS - a reusable and configurable snippet of HTML

Page 16: Twig Brief, Tips&Tricks

XSS protection - escaping

Page 17: Twig Brief, Tips&Tricks

SpacelessUse the spaceless tag to remove whitespace between HTML tags, not whitespace within HTML tags or whitespace in plain text:

{% spaceless %} <div> <strong>foo bar</strong> </div>{% endspaceless %}{# output will be <div><strong>foo bar</strong></div> #}

{% set value = 'no spaces' %}<li> {{- value }} </li>{# outputs '<li>no spaces </li>' #}

Page 18: Twig Brief, Tips&Tricks

VerbatimThe verbatim tag marks sections as being raw text that should not be parsed. For example to put Twig syntax as example into a template you can use this snippet:

{% verbatim %} <ul> {% for item in seq %} <li>{{ item }}</li> {% endfor %} </ul>{% endverbatim %}

You can also use this tag to avoid the conflict with the default angular.js syntax, if you do not want to change it.

Page 19: Twig Brief, Tips&Tricks

The i18n extensionTo use it, first, install the Extensions library.You need to register this extension before using the trans block, then configure the gettext extension:

// Set language to Frenchputenv('LC_ALL=fr_FR');setlocale(LC_ALL, 'fr_FR');// Specify the location of the translation tablesbindtextdomain('myAppPhp', 'includes/locale');bind_textdomain_codeset('myAppPhp', 'UTF-8');// Choose domaintextdomain('myAppPhp');

{% trans "Hello World!" %}

{% trans string_variable %}

{% trans %} Hello {{ name }}{% endtrans %}

Page 20: Twig Brief, Tips&Tricks

EXTENDING AND

CUSTOMIZING

Page 21: Twig Brief, Tips&Tricks

Setting your own custom syntaxYou may want to use simultaneously the default syntax of angular( {{ }} ) with twig - what to do?Change the twig default syntax to your preferred one!

Page 22: Twig Brief, Tips&Tricks

Creating a TWIG extensionTwig is very customizable, and allows you to create custom tools, like tags,

filters, operators, functions by extending the core(lib\twig\Extension\Core.php) .The principle of creating an extension is the same for any element you

wish to customize: you create a class which extends the \Twig_Extension abstract class, then overwrite the desired function, and inject your service or create a custom function which you intend to use in the templates.

Page 23: Twig Brief, Tips&Tricks

use it in your templates:

{{ entityHelper.attributeByStore(promo, attribute) }}

Page 24: Twig Brief, Tips&Tricks

Sandbox• It’s a regular Twig extension, {% sandbox %}• Disabled by default.• It allows to restrict the functions, filters, tags and object properties used in the templates.• It’s based on security policies.

$loader = new Twig_Loader_Filesystem('...');$twig = new Twig_Environment($loader, array());$properties = array(‘User’ => array('name', 'address'));$policy = new Twig_Sandbox_SecurityPolicy(

array(), array(), array(), $properties, array());$sandbox = new Twig_Extension_Sandbox(

$policy, true // all templates are sandboxed);$twig->addExtension($sandbox);

Page 25: Twig Brief, Tips&Tricks

The template now displays an error:

{% sandbox %} {% include 'user.html' %}{% endsandbox %}

{{ user.name }} - ok{{ user.address }} - ok{{ user.age }} - is not accessibleWhoops, looks like something went wrong.User: {{ user.age }}Calling "age" property on a "User" object is not allowed …

Page 26: Twig Brief, Tips&Tricks

Security policy arguments:$policy = new Twig_Sandbox_SecurityPolicy(

$tags,$filters,$methods,$properties,$functions

);

Allow just 3 filters:$policy = new Twig_Sandbox_SecurityPolicy(

$tags,array('escape', 'upper', 'lower'),$methods,$properties,$functions

);

Page 27: Twig Brief, Tips&Tricks

{{ include }} vs {% include %}1) If you want to store contents of a file in a variable if you want to repeat it twice:

{% set content = include('test.twig') %}Instead of:

{% set content %}

{% include 'test.twig' %}

{% endset %}

2) If you want to add filters:

{{ include('alert.twig') | upper }}Its tag equivalent:

{% set temp %} {% include 'alert.twig' %}

{% endset %} {{ temp | upper }}

Also, according to the documentation, it looks recommended to use {{ include() }} to fit with best practices.

Page 28: Twig Brief, Tips&Tricks

Conditional layouts{% extends request.ajax ? "base_ajax.html" : "base.html" %}

{% block content %} This is the content to be displayed.{% endblock %}

Dynamic inclusion of a template:

{% include var|default('index') ~ '_foo.html' %}

Page 29: Twig Brief, Tips&Tricks

Accessing an object attribute{{ user.name }}

name can be:* an item on an array* property on an object* getName()

{{ user[‘name’] }}

or you can force it to *just* fetch “name” as an array item

Page 30: Twig Brief, Tips&Tricks

Convert format and format date

Page 31: Twig Brief, Tips&Tricks

Defensive design

Use a default value when possible:{{ variable|default("value") }}

Ignore missing templates:{% include 'section_' ~ slug ~ '.twig' ignore missing %}

Define fallback templates{% extends ['layout_' ~ locale ~ '.html.twig', 'layout.html.twig'] %}

Page 32: Twig Brief, Tips&Tricks

Render a Template without a custom Controlleracme_privacy:

path: /privacy

defaults:

_controller: FrameworkBundle:Template:template

template: static/privacy.html.twig

maxAge: 86400

sharedAge: 86400

{{ render(url('acme_privacy')) }}

Page 33: Twig Brief, Tips&Tricks

Thank you very much for your attendance!

Page 34: Twig Brief, Tips&Tricks

Useful links:http://twig.sensiolabs.org/

http://symfony.com/doc/current/components/templating/index.html

http://symfony.com/doc/current/cookbook/templating/index.html

http://fabien.potencier.org/article/34/templating-engines-in-php

http://www.slideshare.net/fabpot/twig-the-flexible-fast-and-securetemplate-language-for-php

http://www.slideshare.net/cesaredamico/webtech-twig

http://www.slideshare.net/weaverryan/being-dangerous-with-twig

http://www.slideshare.net/javier.eguiluz/twig-tips-and-tricks