powerful and flexible templates with twig
TRANSCRIPT
Powerful and flexible Powerful and flexible templates with Twigtemplates with TwigMichael Peacock, PHPNE December 2012Michael Peacock, PHPNE December 2012
@michaelpeacock@michaelpeacock
Head Developer @groundsixHead Developer @groundsix
AuthorAuthor
Occasional conference speakerOccasional conference speaker
michaelpeacock.co.ukmichaelpeacock.co.uk
twitter.com/michaelpeacocktwitter.com/michaelpeacock
InstallationInstallation
Create a composer.json fileCreate a composer.json file
Download composerDownload composer
Run composer to install twigRun composer to install twig
{ "require": { "twig/twig": "1.*" }}
curl -s http://getcomposer.org/installer | php
php composer.phar install
SetupSetup
$loader = new \Twig_Loader_Filesystem(__DIR__ . '/templates/');// ideally sits in a dependency injection container$twig = new \Twig_Environment($loader, array('cache' => __DIR__ . '/cache/templates',));
Basic usageBasic usage
$template = $twig->loadTemplate('mytemplate.html.twig');echo $template->render($array_of_template_variables);exit;
Template variablesTemplate variables
Associative arrayAssociative array
Keys are used to access the data in the Keys are used to access the data in the templatestemplates
Values are displayed / rendered in the templatesValues are displayed / rendered in the templates
Values can be:Values can be:
ArraysArrays
ObjectsObjects
DataData
Base templatesBase templates
A base template defines “blocks” which can be A base template defines “blocks” which can be overridden by other templatesoverridden by other templates
The block can contain default content; The block can contain default content; overriding is optionaloverriding is optional
Makes it easy to change small amounts of a Makes it easy to change small amounts of a base template on only a few specific pagesbase template on only a few specific pages
BlocksBlocks
{% block content %}{% endblock %}
{% block content %}<p>This is some default content which will be displayed if the template isused directly or if it isn't overriden by another template</p>{% endblock %}
Extending baseExtending base
Extend your base templateExtend your base template
Override your blocksOverride your blocks
{% include 'base.twig.html' %}
{% block content %}<p>This is overriding the base template</p>{% endblock %}
IncludesIncludes
{% include 'another_template.html.twig' %}
{% include template_name_in_variable %}
{% include template_from_string(variable_containing_twig) %}
A note on contextA note on context
By default all included templates and base By default all included templates and base templates inherit their template variables from templates inherit their template variables from the template you are renderingthe template you are rendering
You can change this by passing a list of You can change this by passing a list of variables when including a templatevariables when including a template
You can also pass You can also pass moremore variables by omitting variables by omitting the the onlyonly keyword keyword
{% include 'another_template.html.twig' with other_variables only %}
Printing variablesPrinting variables
Output is automatically escapedOutput is automatically escaped
But you can tell twig to not escape some data But you can tell twig to not escape some data (using a filter, which we will look at shortly)(using a filter, which we will look at shortly)
{{my_variable}}
{{my_variable|raw}}
Dynamic MagicDynamic Magic
check if foo is an array and bar a valid element; check if foo is an array and bar a valid element;
if not, and if foo is an object, check that bar is a valid if not, and if foo is an object, check that bar is a valid property; property;
if not, and if foo is an object, check that bar is a valid method if not, and if foo is an object, check that bar is a valid method (even if bar is the constructor - use __construct() instead); (even if bar is the constructor - use __construct() instead);
if not, and if foo is an object, check that getBar is a valid if not, and if foo is an object, check that getBar is a valid method; method;
if not, and if foo is an object, check that isBar is a valid if not, and if foo is an object, check that isBar is a valid method; method;
if not, return a null value.if not, return a null value.
{{ foo.bar }}
Source: http://twig.sensiolabs.org/doc/templates.html#variables
Explicit typesExplicit types
You can also instruct twig to call a method on You can also instruct twig to call a method on an object or access a property of an array as an object or access a property of an array as opposed to relying on the dynamic magicopposed to relying on the dynamic magic
{{object.method()}}{{object.method()}}
{{array[‘variable’]}}{{array[‘variable’]}}
Setting variablesSetting variables
You can also create variables on-the-flyYou can also create variables on-the-fly
{% set new_variable = ‘variable’ %}{% set new_variable = ‘variable’ %}
Useful when working with objects or arrays, as Useful when working with objects or arrays, as you can pull out data, manipulate it and use it you can pull out data, manipulate it and use it as a variable in its own rightas a variable in its own right
ConditionsConditions
{% if logged_in_user is not null %}<p>Welcome logged_in_user.name. <a href="/logout">Logout</a></p>{% else %}<p><a href="/login">Login</a></p>{% endif %}
Supported comparisonsSupported comparisons
====
!=!=
<<
>>
>=>=
<=<=
Ternary operatorsTernary operators
{{ logged_in ? logged_in_username : 'guest' }}{{ logged_in ? logged_in_username : 'guest' }}
LoopsLoops
<ul> {% for item in array_or_iterable_object %} <li>item.getName</li> {% else %} <li>No results found</li> {% endfor %}</ul>
Loop dataLoop data
Iteration of a loop (1 indexed)Iteration of a loop (1 indexed)
Parent loop iteration (1 indexed)Parent loop iteration (1 indexed)
Other informationOther information
loop.index0 (0 indexed iteration)loop.index0 (0 indexed iteration)
loop.revindex (reversed index)loop.revindex (reversed index)
loop.first (true if first iteration)loop.first (true if first iteration)
loop.last (truue if last iteration)loop.last (truue if last iteration)
loop.lengthloop.length
{{loop.index}}
{{loop.parent.loop.index}}
ConcatenationConcatenation
~~
FiltersFilters
Many of them are twig wrappers for PHP functionsMany of them are twig wrappers for PHP functions
Date: Date: {{ article.publication_date|date("d/m/Y") }}
Number format {{500123.0123|number_format}}Number format {{500123.0123|number_format}}
Url encode {{variable|url_encode()}}Url encode {{variable|url_encode()}}
Length (of string or items in array) {{variable|Length (of string or items in array) {{variable|length}}length}}
You can use multiple filters e.g. {{var|trans|raw}}You can use multiple filters e.g. {{var|trans|raw}}
Lots more! Lots more! http://twig.sensiolabs.org/doc/filters/index.htmlhttp://twig.sensiolabs.org/doc/filters/index.html
Custom filtersCustom filtersCreate a functionCreate a function
First parameter is what appears before the filter, other First parameter is what appears before the filter, other parameters are set when you use the filter if required (ideally, parameters are set when you use the filter if required (ideally, these should be optional)these should be optional)
Add the filter Add the filter
Use the filterUse the filter
Unfortunately closures can’t be used yetUnfortunately closures can’t be used yet
function twig_filter_gravatar($email, $default='mm', $size=30){return "http://www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?d=" . urlencode($default) . "&s=" . $size;}
$twig->addFilter('gravatar', new \Twig_Filter_Function('twig_filter_gravatar'));
{{user.getEmail|gravatar}}
TwigTwig
Powerful, flexible templatesPowerful, flexible templates
Easy to build and extendEasy to build and extend
Syntax thats friendly for designersSyntax thats friendly for designers
Allows some level of control in the templatesAllows some level of control in the templates
A bit of a double edged sword - with great A bit of a double edged sword - with great template flexibility comes great responsibility!template flexibility comes great responsibility!
http://twig.sensiolabs.org/http://twig.sensiolabs.org/