PHP Compilation and Cache
{# just say hello #}
Hello {{ name }}!
Slide 21
Slide 21 text
PHP Compilation and Cache
class __TwigTemplate_df6deba4655fee022981430 extends Twig_Template
{
protected function doDisplay(array $context, array $blocks = array())
{
// line 1
echo "Hello ";
echo twig_escape_filter($this->env, (isset($context["name"]) ?
$context["name"] : null), "html", null, true);
echo "!";
}
// ...
}
Escaping is enabled
Slide 22
Slide 22 text
Debugging
Slide 23
Slide 23 text
Accurate Debugging
Hello {{ rand(['John', 'Tom', 'Paul']) }}!
Twig_Error_Syntax: The function
"rand" does not exist. Did you mean
"random" in "hello.twig" at line 3
Slide 24
Slide 24 text
Dumping a Variable
{% set names = ['John', 'Tom', 'Paul'] %}
{{ dump(names) }}
Slide 25
Slide 25 text
Strict Variables Enabled
Hello {{ nam }}!
Twig_Error_Runtime: Variable "nam"
does not exist in "hello.twig" at
line 1
Slide 26
Slide 26 text
Output escaping
Slide 27
Slide 27 text
Automatic Output Escaping
Hello {{ name }}!
The variable is automatically escaped if it
contains a string
Output Escaping
{% autoescape %}
Everything will be automatically escaped in this block
using the HTML strategy
{% endautoescape %}
{% autoescape 'js' %}
Everything will be automatically escaped in this block
using the js escaping strategy
{% endautoescape %}
{% autoescape false %}
Everything will be outputted as is in this block
{% endautoescape %}x
Slide 30
Slide 30 text
Variables
Slide 31
Slide 31 text
Variables Abstraction
{{ article.title }}
The article can be an
array or an object.
The title can be a key of
the array, a public
property, a regular
method or a getter
method.
Making Decisions
{% if product.stock > 10 %}
Available
{% elseif product.stock > 0 %}
Only {{ product.stock }} left!
{% else %}
Sold-out!
{% endif %}
Slide 35
Slide 35 text
Iterating Over a Collection
{% for post in posts if post.active %}
{{ post.title }}
{{ post.body }}
{% else %}
No published posts yet.
{% endfor %}
Slide 36
Slide 36 text
Get the Loop Context
Variable Description
loop.index The current iteration of the loop. (1 indexed)
loop.index0 The current iteration of the loop. (0 indexed)
loop.revindex The number of iterations from the end of the loop (1 indexed)
loop.revindex0 The number of iterations from the end of the loop (0 indexed)
loop.first True if rst iteration
loop.last True if last iteration
loop.length The number of items in the sequence
loop.parent The parent context
Slide 37
Slide 37 text
Operators
Slide 38
Slide 38 text
Operators
o Math: +, -, /, *, **, %
o Logical: or, and, xor
o Concatenation: ~
o Comparison: <, >, <=, >=, ==
o Containment: in, not in
Slide 39
Slide 39 text
Functions
Slide 40
Slide 40 text
Generating Contents
Hello {{ random(['John', 'Tom', 'Paul']) }}!
{% for i in range(0,10) %}
{{ cycle(['odd', 'even'], i) }}
{% endfor %}
Slide 41
Slide 41 text
Built-in Functions
o attribute
o block
o constant
o cycle
o date
o parent
o random
o range
Built-in Filters
o abs
o capitalize
o convert_encoding
o date
o date_modify
o default
o escape
o format
o join
o json_encode
o keys
o length
o lower
o merge
o nl2br
o number_format
o raw
o replace
o reverse
o slice
o sort
o striptags
o title
o trim
o upper
o url_encode
Slide 45
Slide 45 text
Whitespace Control
Slide 46
Slide 46 text
Whitespace Control
{% spaceless %}
Hello {{ name }}!
{% endspaceless %}
Hello Hugo!
Slide 47
Slide 47 text
Whitespace Control
Hello {{- name }} !
Hello Hugo !
Value is trimmed on the left.
Slide 48
Slide 48 text
Template inclusion
Slide 49
Slide 49 text
Template Inclusion
{%
include "list.twig" with {
"section": "blog",
"posts": articles
} only
%}
The included template is
rendered with its own
context.
Isolation
Slide 50
Slide 50 text
Template inheritance
Slide 51
Slide 51 text
layout.twig
{% block body %}
{% endblock body %}
{% block breadcrumb %} ... {% endblock %}
blog.twig
{% extends "layout.twig" %}
{% block breadcrumb %}
{{ parent() }} - Blog
{% endblock breadcrumb %}
{% block body %}
{% include "posts.twig" %}
{% endblock body %}
Template Inheritance
Extend the parent
template.
Reuse the parent
block default value.
Fill the parent body
block.
Slide 53
Slide 53 text
No content
Slide 54
Slide 54 text
Macros
Slide 55
Slide 55 text
Defining Macros
{% macro input(name, value, type, size) %}
{% endmacro %}
Default argument values are
defined with the default filter
Slide 56
Slide 56 text
Using Macros
{% import "forms.html" as forms %}
{{ forms.input('username') }}
Macros are imported under
a specific namespace
The macro is called with the
prefixed namespace
Enabling Sandbox Mode
$policy = new Twig_Sandbox_SecurityPolicy(
$tags,
$filters,
$methods,
$properties,
$functions
);
$sandbox = new Twig_Extension_Sandbox($policy);
$twig = new Twig_Environment();
$twig->addExtension($sandbox);
Slide 60
Slide 60 text
Using the Sandbox Mode
{% sandbox %}
{% include 'users.html' %}
{% endsandbox %}
Slide 61
Slide 61 text
Enabling Sandbox Mode
$sandbox = new Twig_Extension_Sandbox($policy, true);
Sandbox mode is
automatically enabled for all
template
Slide 62
Slide 62 text
Enabling Sandbox Mode
{% block foo 'bar' %}
{% include 'users.html' %}
Twig_Sandbox_SecurityError:
Tag "block" is not allowed in
"hello.twig" at line 2
Customizing Twig T
ags
$twig = new Twig_Environment();
$lexer = new Twig_Lexer($twig, array(
'tag_comment' => array('{*', '*}'),
'tag_block' => array('{', '}'),
'tag_variable' => array('{$', '}'),
));
$twig->setLexer($lexer);
Smarty tags
Slide 71
Slide 71 text
Twig extensions
Slide 72
Slide 72 text
Extending the Twig Gramar
o Global variables
o Global functions
o Filters
o Tests
o Operators
o T
ags
Slide 73
Slide 73 text
Built-in Extensions
Exension name Description
Core Provides the core features
Debug Provides debugging tools like the dump() function
Escaper Provides escaping tools
Optimizer Provides optimization tools
Sandbox Provides the sandboxed environment capabilities
Slide 74
Slide 74 text
The Twig Extension Class
abstract class Twig_Extension implements
Twig_ExtensionInterface
{
public function initRuntime(Twig_Environment $environment);
public function getTokenParsers();
public function getNodeVisitors();
public function getFilters();
public function getTests();
public function getFunctions();
public function getOperators();
public function getGlobals();
}
Slide 75
Slide 75 text
Creating a Twig Extension
class GravatarExtension extends \Twig_Extension
{
public function getName()
{
return 'gravatar';
}
}
The abstract getName()
method must be
implemented.
Slide 76
Slide 76 text
Registering the Extension
$extension = new GravatarExtension();
$twig = new Twig_Environment();
$twig->addExtension($extension);
Easy uh?!
Slide 77
Slide 77 text
Adding a new Global Function
class GravatarExtension extends \Twig_Extension
{
public function getFunctions()
{
return array(
'gravatar' => new \Twig_Function_Method($this, 'getGravatar'),
);
}
public function getGravatar($email, $size = '80', $rating = 'g')
{
$url = 'http://www.gravatar.com/avatar/%s?size=%u&rating=%s';
$hash = md5(strtolower(trim($email)));
return sprintf($url, $hash, (int) $size, $rating);
}
}
Slide 78
Slide 78 text
Using the Global Function
{% set uri = gravatar("[email protected]") %}
Twig now knows this
function.
Slide 79
Slide 79 text
4.
Frameworks & CMS
Slide 80
Slide 80 text
I want to use Twig
with my favorite
framework or CMS!
Drupal 7
Drupal themes
Switch/Case tag
I18n capabilities
Extra filters
Extra functions
http://drupal.org/sandbox/ReneB/1075966
Slide 86
Slide 86 text
WordPress
o http://wordpress.org/extend/plugins/ap-twig-bridge/
o http://inchoo.net/wordpress/twig-wordpress-part2/
o https://github.com/cordoval/Twig-for-WordPress
o https://github.com/maxcal/Twigpress
Slide 87
Slide 87 text
Questions
?
Slide 88
Slide 88 text
Join us in Berlin!
Symfony Live
November 22nd – 23rd