SlideShare a Scribd company logo
Making Sense
of Twig
Brandon Kelly
What is Twig?
It’s a templating language.
!
All templating features are
available globally to all
templates in any context,
as part of the language.
!
It’s not up to each and every
application feature to
provide its own tags.
It’s super powerful.
!
- Many ways to stay DRY
- Custom variables
- Functions
- Filters
- It knows math
- Whitespace control
- Extensible
Templates get compiled into
PHP, so it’s super fast.
Twig even makes debugging a
piece of cake.
Used by some popular apps:
!
- LemonStand
- Symfony
- Craft
- others
twig.sensiolabs.org
The Language
Types of Tags
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
{% block main %}
<p>Hey!</p>
{% endblock %}
</body>
</html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
{% block main %}
<p>Hey!</p>
{% endblock %}
</body>
</html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
{% block main %}
<p>Hey!</p>
{% endblock %}
</body>
</html>
Twig code always lives
within one of these three
tag pairs:
!
{# ... #}
{{ ... }}
{% ... %}
{# ... #}
Comment Tags
Comment tags are like HTML
comments, except they won’t
show up in the page source.
!
{# This won’t make it to
the page source #}
!
<!-- This will -->
{{ ... }}
Output Tags
Output tags output stuff to
the browser.
!
{{ title }}
!
{{ "Howdy" }}
!
{{ 84 / 2 }}
{% ... %}
Logic Tags
Logic tags (or just “tags”)
control the logic of the
template:
!
- Conditionals
- Loops
- Variable definitions
- Macros
- Template includes
- etc.
The syntax varies from tag
to tag.
Some are just a single word.
!
{% requireLogin %}
Some take parameters.
!
{% exit 404 %}
Some have a closing tag.
!
{% block content %}
<p>Hey</p>
{% endblock %}
Some even have nested tags.
!
{% if foo %}
<p>Something</p>
{% else %}
<p>Something else</p>
{% endif %}
It really all depends on
the tag.
!
The only thing they have in
common is that they all start
with “{%”, followed by the
tag name.
!
{% tagname ...
Twig comes with several
built-in tags.
!
{% autoescape %}
{% block %}
{% filter %}
{% do %}
{% embed %}
{% extends %}
{% autoescape %}
{% flush %}
{% for %}
{% from %}
{% if %}
{% import %}
{% include %}
{% macro %}
{% sandbox %}
{% set %}
{% spaceless %}
{% use %}
{% verbatim %}
{% autoescape %}
!
Escapes text for HTML.
!
{% autoescape %}
<p>Hey</p>
{% endautoescape %}
=> &lt;p&gt;Hey&lt;/p&gt;
{% autoescape %} (Cont.)
!
...or Javascript
!
{% autoescape "js" %}
http://foo.com
{% endautoescape %}
=> httpx3Ax2Fx2Ffoo.com
{% spaceless %}
!
Removes any whitespace
between Twig/HTML tags.
!
{%- spaceless %}
<p>Hey there</p>
{% endspaceless -%}
=> <p>Hey there</p>
{% verbatim %}
!
Defines template code that
Twig should output as-is,
without parsing.
!
{% verbatim %}
<p>Type “{{ foo }}”.</p>
{% endverbatim %}
=> <p>Type “{{ foo }}”.</p>
You never put a Twig tag
inside another Twig tag.
!
Bad:
!
{{ "Hey {{ firstName }}" }}
!
Good:
!
{{ "Hey " ~ firstName }}
Values, Expressions,

and Variables
Twig supports five different
types of values.
!
Strings: "Hey" / 'Hey'
Numbers: 42 / 3.14
Booleans: true / false
Arrays: ['a', 'b', 'c']
Objects: { foo: 'bar' }
An expression is either a solo
value, or multiple values
combined to form another value.
!
"Hey" => "Hey"
"Hey "~"there" => "Hey there"
10 => 10
true => true
['a','b','c'] => ['a','b','c']
"Day "~1 => "Day 1"
10*(5+5) => 100
Variables are values that get
set to a name, to be
referenced later.
!
Use the {% set %} tag to
create them.
!
{% set foo = "foo" %}
{% set a = 42 %}
{% set foobar = foo~"bar" %}
The {% set %} tag can also be
used as a tag pair.
!
{% set foo %}
<p>foo</p>
{% endset %}
!
That’s the same as:
!
{% set foo = "n
<p>foo</p>n
" %}
Variables are one tool for
keeping our templates DRY.
!
{% set title = "About Us" %}
...
<title>{{ title }}</title>
...
<h1>{{ title }}</h1>
Filters
Filters modify values.
!
They can uppercase text,
merge arrays, and lots of
other things.
To pass a value through a
filter, type a pipe (“|”)
after the value, followed by
the filter name.
!
"foo"|upper => "FOO"
21.3|round => 21
['a','b','c']|length => 3
Some accept arguments.
!
"foobar"|slice(0,3)
=> foo
You can even chain them.
!
"foobar"|slice(0,3)|upper
=> FOO
You can add filters to
variables, too.
!
{% set foo = "foo" %}
{{ foo|length }}
=> 3
You can use them in pretty
much any context you can
think of.
!
{{ value|filter }}
!
{% set foo = value|filter %}
!
{% do func(value|filter) %}
Filters only modify the value
directly before the filter.
!
"foo"~"bar"|upper
=> fooBAR
!
("foo"~"bar")|upper
=> FOOBAR
Twig comes with tons of
built-in filters:
|abs
|batch
|capitalize
|covert_encoding
|date
|date_modify
|default
|escape
|first
|format
|join
|json_encode
|keys
|last
|length
|lower
|nl2br
|number_format
|merge
|upper
|raw
|replace
|reverse
|round
|slice
|sort
|split
|striptags
|title
|trim
|url_encode
|length
!
Finds the length of a string
or array.
!
{{ "foobar"|length }}
=> 6
!
{{ [1, 2, 3]|length }}
=> 3
|upper & |lower
!
Modify the casing of a
string.
!
{{ "foo"|upper }}
=> FOO
!
{{ "BAR"|lower }}
=> bar
|raw
!
Protects a string from
getting escaped.
!
{{ "<p>Hey</p>" }}
=> &lt;p&gt;Hey&lt;/&gt;
!
{{ "<p>Hey</p>"|raw }}
=> <p>Hey</p>
|date
!
Formats a date.
!
{{ now|date("F j, Y") }}
=> April 23, 2014
Functions
Functions perform functions.
!
To call one, type its name,
followed by parentheses.
!
{{ parent() }}
Many functions accept
arguments:
!
random(1, 10)
Some of them are global:
!
{{ dump(foo) }}
!
And they can also be nested
within objects:
!
{{ craft.isLocalized() }}
Twig comes with a few global
functions built-in:
attribute()
block()
constant()
cycle()
date()
dump()
include()
max()
min()
parent()
random()
range()
source()
template_from_string()
min() & max()
!
Returns the smallest/largest
value in a given array.
!
{{ min([1, 2, 3]) }}
=> 1
!
{{ max([1, 2, 3]) }}
=> 3
random()
!
{{ random("foobar") }}
=> f/o/b/a/r
!
{{ random([1, 2, 3]) }}
=> 1/2/3
!
{{ random(10) }}
=> 1/2/3/4/5/6/7/8/9/10
range()
!
Creates a range of numbers as
an array.
!
{% set r = range(1, 5) %}
=> [1, 2, 3, 4, 5]
!
{% set r = [1..5] %}
=> [1, 2, 3, 4, 5]
dump()
!
Outputs information about a
given variable. Helpful when
debugging.
!
{{ dump(foo) }}
!
(In Craft, dump() is only
available in Dev Mode.)
Conditionals
You can prevent certain parts
of your template from
executing unless a certain
condition is met by wrapping
it in conditional tags.
Conditionals always open with
an {% if %} tag, and close
with an {% endif %} tag.
!
{% if user %}
<p>Hey there handsome!</p>
{% endif %}
You can also specify template
code to be executed if the
condition doesn’t pass, using
the {% else %} tag.
!
{% if user %}
<p>Hey there handsome!</p>
{% else %}
<p>Have we met?</p>
{% endif %}
There’s also an {% elseif %} tag
if you need fallback conditions.
!
{% if user %}
<p>Hey there handsome!</p>
{% elseif username %}
<p>Is this {{ username }}?</p>
{% else %}
<p>Have we met?</p>
{% endif %}
Conditionals can be nested.
!
{% if user %}
{% if user.male %}
<p>Hey there handsome!</p>
{% else %}
<p>Hey pretty lady!</p>
{% endif %}
{% elseif username %}
<p>Is this {{ username }}?</p>
{% else %}
<p>Have we met?</p>
{% endif %}
A single condition can be
made up of multiple
expressions joined together
with “and” or “or”.
!
{% if foo and bar %}
!
{% if foo or bar %}
You can negate a condition by
typing “not” before it.
!
{% if not foo %}
You can also group
expressions together using
parentheses.
!
{% if foo and (
foo == "foo" or
foo == "bar"
) %}
Tests
Tests are little conditional
helpers. They don’t have to
be used within conditionals,
but usually are.
To write a test, add either
“is” or “is not” after a
variable, followed by the
test name.
!
{% if foo is defined %}
!
{% if foo is not empty %}
Twig comes with a few tests
built-in.
!
is constant
is defined
is divisible by
is empty
is even
is iterable
is null
is odd
is same as
is defined
!
Tests whether a variable
exists at all, without Twig
getting mad at you if
it’s not.
!
{% if foo is defined %}
is divisible by
!
Tests whether a number is
divisible by another.
!
{% if 5 is divisible by(2) %}
!
That’s similar to writing:
!
{% if 5 % 2 == 0 %}
is even & is odd
!
Tests whether a number is
even/odd.
!
{% if 5 is even %}
!
{% if 5 is odd %}
is empty
!
Tests whether a variable is
“empty”.
!
{% if foo is not empty %}
!
That’s the same as writing:
!
{% if foo %}
is same as
!
Tests whether two variables
have the same *type*.
!
{% if 5 == "5" %}
=> true
!
{% if 5 is same as "5" %}
=> false
Working with
Arrays and Objects
Arrays and objects both
contain multiple values.
Arrays contain values in a
specific order, and have an
inherent numerical index.
!
{% set arr = ['a','b','c'] %}
!
{{ arr[0] }} => 'a'
{{ arr[1] }} => 'b'
{{ arr[2] }} => 'c'
Objects contain key-value
pairs, and the order is
generally less important.
!
{% set obj = {
foo: "Foo",
bar: "Bar"
} %}
!
{{ obj.foo }} => "Foo"
{{ obj.bar }} => "Bar"
You can merge arrays together
with the ‘merge’ filter.
!
{% set a1 = ['a','b'] %}
{% set a2 = ['c','d'] %}
{% set a3 = a1|merge(a2) %}
!
=> ['a','b','c','d']
You can merge objects
together too.
!
{% set o1 = {foo: "Foo"} %}
{% set o2 = {bar: "Bar"} %}
{% set o3 = o1|merge(o2) %}
!
=> {foo: "Foo", bar: "Bar"}
You can grab part of an array
with the “slice” filter.
!
{% set a1 = ['a','b','c'] %}
{% set a2 = a1|slice(0, 2) %}
!
=> ['a','b']
!
A shortcut is also available:
!
{% set a2 = a1[0:2] %}
Looping through

arrays and objects
You can loop through arrays with
the {% for %} tag.
!
The syntax is:
!
{% for itemname in myarray %}
...
{% endfor %}
!
The 2nd param (“itemname”) is
whatever you want to call each
item within the array.
Example 1: Age field
!
<select name="age">
{% for age in [0..150] %}
<option>
{{ age }}</option>
{% endfor %}
</select>
Example 2: Exp. Year field
!
{% set y1 = now.year %}
{% set y2 = y1 + 10 %}
!
<select name="exp_year">
{% for year in [y1..y2] %}
<option>
{{ year }}</option>
{% endfor %}
</select>
Example 3: Navigation
!
{% set nav = [
{ title: "Home", uri: "" },
{ title: "About", uri: "about" }
] %}
!
<nav>
{% for item in nav %}
<a href="{{ url(item.uri) }}">
{{ item.title }}</a>
{% endfor %}
</nav>
DRY Templating
Includes
Templates can include others.
Include
Template
Parent
Template
Parent
Template
Use the {% include %} tag to
include another template
wherever the tag is placed.
!
{% include "some/template" %}
By default, any variables
available to the “parent”
template will also be available
in the included template.
!
{% set foo = "foo" %}
{% include "myinclude" %}
!
myinclude.html:
{{ foo }}
=> foo
You can define additional
variables just for the included
template using the “with” param.
!
{% include "myinclude"
with { foo: "foo" }
%}
!
some/template.html:
{{ foo }}
=> foo
To *only* pass certain variables
to the included template, use the
“only” param.
!
{% set foo = "foo" %}
{% include "myinclude"
with { bar: "bar" } only
%}
!
some/template.html:
{% if foo is defined %}
=> false
Extending Templates
A template can extend
another, overriding parts of
it (called “blocks”).
Parent Template
Block
Child Template Child Template
Define overridable areas in
the parent template using the
{% block %} tag.
!
<body>
{% block body %}
<p>Default content</p>
{% endblock %}
</body>
Use the {% extends %} tag
within your child template to
tell it which template it
extends.
!
{% extends "layout" %}
Override the parent’s blocks
by creating new blocks in the
child template with the same
name.
!
{% extends "layout" %}
!
{% block body %}
<p>Override content</p>
{% endblock %}
You can output the parent
block’s content using the
parent() function.
!
{% extends "layout" %}
!
{% block body %}
{{ parent() }}
<p>Additional content</p>
{% endblock %}
Multi-level inheritance is
totally possible.
Embedding Templates
Twig also lets you “embed”
other templates, which is
similar to including them,
except you get to override
the child template’s blocks
in the process.
Use the {% embed %} tag to
embed another template.
!
{% embed "promo" %}
{% block body %}
{{ parent() }}
<span class="ribbon">
50% off!
</span>
{% endblock %}
{% endembed %}
Macros
Macros are like includes that
are defined right within
another template.
Use the {% macro %} tag to
define them.
!
{% macro errors(list) %}
{% if list|length %}
<ul class="errors">
{% for error in list %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
You must import macros before
you can use them, with either
{% from %} or {% import %}.
!
{% from _self import errors %}
{{ errors(entry.allErrors) }}
!
!
{% import _self as m %}
{{ m.errors(entry.allErrors) }}
You can import macros from other
templates, too.
!
{% from "macros" import errors %}
{{ errors(entry.allErrors) }}
!
!
{% import "macros" as m %}
{{ m.errors(entry.allErrors) }}
!
The End.

More Related Content

What's hot

Apache Velocity 1.6
Apache Velocity 1.6Apache Velocity 1.6
Apache Velocity 1.6
Henning Schmiedehausen
 
Php string function
Php string function Php string function
Php string function
Ravi Bhadauria
 
Open Source Package PHP & MySQL
Open Source Package PHP & MySQLOpen Source Package PHP & MySQL
Open Source Package PHP & MySQL
kalaisai
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
Jason Austin
 
PHP - Introduction to PHP Functions
PHP -  Introduction to PHP FunctionsPHP -  Introduction to PHP Functions
PHP - Introduction to PHP Functions
Vibrant Technologies & Computers
 
PHP
PHP PHP
Class 2 - Introduction to PHP
Class 2 - Introduction to PHPClass 2 - Introduction to PHP
Class 2 - Introduction to PHP
Ahmed Swilam
 
Codeware
CodewareCodeware
Codeware
Uri Nativ
 
Twig integration
Twig integrationTwig integration
Twig integration
Thijs De Paepe
 
Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
Richard McIntyre
 
Data Types In PHP
Data Types In PHPData Types In PHP
Data Types In PHP
Mark Niebergall
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
Wildan Maulana
 
Php i basic chapter 3
Php i basic chapter 3Php i basic chapter 3
Php i basic chapter 3
Muhamad Al Imran
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
Anis Ahmad
 
Introduction to PHP Lecture 1
Introduction to PHP Lecture 1Introduction to PHP Lecture 1
Introduction to PHP Lecture 1
Ajay Khatri
 
Basic PHP
Basic PHPBasic PHP
Basic PHP
Todd Barber
 
Lca05
Lca05Lca05
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)
Ajay Khatri
 
Using PHP
Using PHPUsing PHP
Using PHP
Mark Casias
 
07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards
Denis Ristic
 

What's hot (20)

Apache Velocity 1.6
Apache Velocity 1.6Apache Velocity 1.6
Apache Velocity 1.6
 
Php string function
Php string function Php string function
Php string function
 
Open Source Package PHP & MySQL
Open Source Package PHP & MySQLOpen Source Package PHP & MySQL
Open Source Package PHP & MySQL
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
PHP - Introduction to PHP Functions
PHP -  Introduction to PHP FunctionsPHP -  Introduction to PHP Functions
PHP - Introduction to PHP Functions
 
PHP
PHP PHP
PHP
 
Class 2 - Introduction to PHP
Class 2 - Introduction to PHPClass 2 - Introduction to PHP
Class 2 - Introduction to PHP
 
Codeware
CodewareCodeware
Codeware
 
Twig integration
Twig integrationTwig integration
Twig integration
 
Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
 
Data Types In PHP
Data Types In PHPData Types In PHP
Data Types In PHP
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
Php i basic chapter 3
Php i basic chapter 3Php i basic chapter 3
Php i basic chapter 3
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
Introduction to PHP Lecture 1
Introduction to PHP Lecture 1Introduction to PHP Lecture 1
Introduction to PHP Lecture 1
 
Basic PHP
Basic PHPBasic PHP
Basic PHP
 
Lca05
Lca05Lca05
Lca05
 
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)
 
Using PHP
Using PHPUsing PHP
Using PHP
 
07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards
 

Viewers also liked

Drupal 8: TWIG Template Engine
Drupal 8:  TWIG Template EngineDrupal 8:  TWIG Template Engine
Drupal 8: TWIG Template Engine
drubb
 
Drupal 8 templating with twig
Drupal 8 templating with twigDrupal 8 templating with twig
Drupal 8 templating with twig
Taras Omelianenko
 
Drupal 8: Theming
Drupal 8: ThemingDrupal 8: Theming
Drupal 8: Theming
drubb
 
Things Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & DrupalThings Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & Drupal
lucenerevolution
 
Single Page Applications in Drupal
Single Page Applications in DrupalSingle Page Applications in Drupal
Single Page Applications in Drupal
Chris Tankersley
 
Drupal 8: Entities
Drupal 8: EntitiesDrupal 8: Entities
Drupal 8: Entities
drubb
 
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
Dropsolid
 
Intro to Apache Solr for Drupal
Intro to Apache Solr for DrupalIntro to Apache Solr for Drupal
Intro to Apache Solr for Drupal
Chris Caple
 
Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8
Anne Tomasevich
 
No pain, no gain. CSS Code Reviews FTW.
No pain, no gain. CSS Code Reviews FTW.No pain, no gain. CSS Code Reviews FTW.
No pain, no gain. CSS Code Reviews FTW.
Stacy Kvernmo
 
Drupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + DockerDrupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + Docker
Roald Umandal
 
Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8
Brian Ward
 
Atomic design
Atomic designAtomic design
Atomic design
Brad Frost
 

Viewers also liked (13)

Drupal 8: TWIG Template Engine
Drupal 8:  TWIG Template EngineDrupal 8:  TWIG Template Engine
Drupal 8: TWIG Template Engine
 
Drupal 8 templating with twig
Drupal 8 templating with twigDrupal 8 templating with twig
Drupal 8 templating with twig
 
Drupal 8: Theming
Drupal 8: ThemingDrupal 8: Theming
Drupal 8: Theming
 
Things Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & DrupalThings Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & Drupal
 
Single Page Applications in Drupal
Single Page Applications in DrupalSingle Page Applications in Drupal
Single Page Applications in Drupal
 
Drupal 8: Entities
Drupal 8: EntitiesDrupal 8: Entities
Drupal 8: Entities
 
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
 
Intro to Apache Solr for Drupal
Intro to Apache Solr for DrupalIntro to Apache Solr for Drupal
Intro to Apache Solr for Drupal
 
Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8Building a Custom Theme in Drupal 8
Building a Custom Theme in Drupal 8
 
No pain, no gain. CSS Code Reviews FTW.
No pain, no gain. CSS Code Reviews FTW.No pain, no gain. CSS Code Reviews FTW.
No pain, no gain. CSS Code Reviews FTW.
 
Drupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + DockerDrupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + Docker
 
Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8
 
Atomic design
Atomic designAtomic design
Atomic design
 

Similar to Making Sense of Twig

Lettering js
Lettering jsLettering js
Lettering js
davatron5000
 
Php
PhpPhp
Template Toolkit
Template ToolkitTemplate Toolkit
Template Toolkit
dwm042
 
8. radio1 in Symfony 4
8. radio1 in Symfony 48. radio1 in Symfony 4
8. radio1 in Symfony 4
Razvan Raducanu, PhD
 
Asp.Net MVC - Razor Syntax
Asp.Net MVC - Razor SyntaxAsp.Net MVC - Razor Syntax
Asp.Net MVC - Razor Syntax
Renier Serven
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentation
bryanbibat
 
PHP MySQL
PHP MySQLPHP MySQL
Jekyll - Liquid for noobs
Jekyll - Liquid for noobsJekyll - Liquid for noobs
Jekyll - Liquid for noobs
Bruno Mendes
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern Perl
Dave Cross
 
9. lower in Symfony 4
9. lower in Symfony 49. lower in Symfony 4
9. lower in Symfony 4
Razvan Raducanu, PhD
 
Component and Event-Driven Architectures in PHP
Component and Event-Driven Architectures in PHPComponent and Event-Driven Architectures in PHP
Component and Event-Driven Architectures in PHP
Stephan Schmidt
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertext
frankieroberto
 
Php essentials
Php essentialsPhp essentials
Php essentials
sagaroceanic11
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
James Gray
 
course slides -- powerpoint
course slides -- powerpointcourse slides -- powerpoint
course slides -- powerpoint
webhostingguy
 
Let's write a PDF file
Let's write a PDF fileLet's write a PDF file
Let's write a PDF file
Ange Albertini
 
Php + my sql
Php + my sqlPhp + my sql
Php + my sql
Ashen Disanayaka
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
James Gray
 
11. move in Symfony 4
11. move in Symfony 411. move in Symfony 4
11. move in Symfony 4
Razvan Raducanu, PhD
 
Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1
Gheyath M. Othman
 

Similar to Making Sense of Twig (20)

Lettering js
Lettering jsLettering js
Lettering js
 
Php
PhpPhp
Php
 
Template Toolkit
Template ToolkitTemplate Toolkit
Template Toolkit
 
8. radio1 in Symfony 4
8. radio1 in Symfony 48. radio1 in Symfony 4
8. radio1 in Symfony 4
 
Asp.Net MVC - Razor Syntax
Asp.Net MVC - Razor SyntaxAsp.Net MVC - Razor Syntax
Asp.Net MVC - Razor Syntax
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentation
 
PHP MySQL
PHP MySQLPHP MySQL
PHP MySQL
 
Jekyll - Liquid for noobs
Jekyll - Liquid for noobsJekyll - Liquid for noobs
Jekyll - Liquid for noobs
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern Perl
 
9. lower in Symfony 4
9. lower in Symfony 49. lower in Symfony 4
9. lower in Symfony 4
 
Component and Event-Driven Architectures in PHP
Component and Event-Driven Architectures in PHPComponent and Event-Driven Architectures in PHP
Component and Event-Driven Architectures in PHP
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertext
 
Php essentials
Php essentialsPhp essentials
Php essentials
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
 
course slides -- powerpoint
course slides -- powerpointcourse slides -- powerpoint
course slides -- powerpoint
 
Let's write a PDF file
Let's write a PDF fileLet's write a PDF file
Let's write a PDF file
 
Php + my sql
Php + my sqlPhp + my sql
Php + my sql
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
11. move in Symfony 4
11. move in Symfony 411. move in Symfony 4
11. move in Symfony 4
 
Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1
 

Recently uploaded

TMU毕业证书精仿办理
TMU毕业证书精仿办理TMU毕业证书精仿办理
TMU毕业证书精仿办理
aeeva
 
ppt on the brain chip neuralink.pptx
ppt  on   the brain  chip neuralink.pptxppt  on   the brain  chip neuralink.pptx
ppt on the brain chip neuralink.pptx
Reetu63
 
The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
Yara Milbes
 
Kubernetes at Scale: Going Multi-Cluster with Istio
Kubernetes at Scale:  Going Multi-Cluster  with IstioKubernetes at Scale:  Going Multi-Cluster  with Istio
Kubernetes at Scale: Going Multi-Cluster with Istio
Severalnines
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
kalichargn70th171
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Paul Brebner
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom KittEnhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Peter Caitens
 
🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻
🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻
🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻
campbellclarkson
 
Orca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container OrchestrationOrca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container Orchestration
Pedro J. Molina
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
42 Ways to Generate Real Estate Leads - Sellxpert
42 Ways to Generate Real Estate Leads - Sellxpert42 Ways to Generate Real Estate Leads - Sellxpert
42 Ways to Generate Real Estate Leads - Sellxpert
vaishalijagtap12
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio, Inc.
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
XfilesPro
 
Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)
alowpalsadig
 
14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision
ShulagnaSarkar2
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdfBaha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid
 

Recently uploaded (20)

TMU毕业证书精仿办理
TMU毕业证书精仿办理TMU毕业证书精仿办理
TMU毕业证书精仿办理
 
ppt on the brain chip neuralink.pptx
ppt  on   the brain  chip neuralink.pptxppt  on   the brain  chip neuralink.pptx
ppt on the brain chip neuralink.pptx
 
The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
 
Kubernetes at Scale: Going Multi-Cluster with Istio
Kubernetes at Scale:  Going Multi-Cluster  with IstioKubernetes at Scale:  Going Multi-Cluster  with Istio
Kubernetes at Scale: Going Multi-Cluster with Istio
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
Why Apache Kafka Clusters Are Like Galaxies (And Other Cosmic Kafka Quandarie...
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom KittEnhanced Screen Flows UI/UX using SLDS with Tom Kitt
Enhanced Screen Flows UI/UX using SLDS with Tom Kitt
 
🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻
🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻
🏎️Tech Transformation: DevOps Insights from the Experts 👩‍💻
 
Orca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container OrchestrationOrca: Nocode Graphical Editor for Container Orchestration
Orca: Nocode Graphical Editor for Container Orchestration
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
42 Ways to Generate Real Estate Leads - Sellxpert
42 Ways to Generate Real Estate Leads - Sellxpert42 Ways to Generate Real Estate Leads - Sellxpert
42 Ways to Generate Real Estate Leads - Sellxpert
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
 
Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)Photoshop Tutorial for Beginners (2024 Edition)
Photoshop Tutorial for Beginners (2024 Edition)
 
14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
 
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
 
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdfBaha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
Baha Majid WCA4Z IBM Z Customer Council Boston June 2024.pdf
 

Making Sense of Twig

  • 3. It’s a templating language. ! All templating features are available globally to all templates in any context, as part of the language. ! It’s not up to each and every application feature to provide its own tags.
  • 4. It’s super powerful. ! - Many ways to stay DRY - Custom variables - Functions - Filters - It knows math - Whitespace control - Extensible
  • 5. Templates get compiled into PHP, so it’s super fast.
  • 6. Twig even makes debugging a piece of cake.
  • 7. Used by some popular apps: ! - LemonStand - Symfony - Craft - others
  • 11. <html> <head> <title>{{ title }}</title> </head> <body> <h1>{{ title }}</h1> {% block main %} <p>Hey!</p> {% endblock %} </body> </html>
  • 12. <html> <head> <title>{{ title }}</title> </head> <body> <h1>{{ title }}</h1> {% block main %} <p>Hey!</p> {% endblock %} </body> </html>
  • 13. <html> <head> <title>{{ title }}</title> </head> <body> <h1>{{ title }}</h1> {% block main %} <p>Hey!</p> {% endblock %} </body> </html>
  • 14. Twig code always lives within one of these three tag pairs: ! {# ... #} {{ ... }} {% ... %}
  • 16. Comment tags are like HTML comments, except they won’t show up in the page source. ! {# This won’t make it to the page source #} ! <!-- This will -->
  • 18. Output tags output stuff to the browser. ! {{ title }} ! {{ "Howdy" }} ! {{ 84 / 2 }}
  • 20. Logic tags (or just “tags”) control the logic of the template: ! - Conditionals - Loops - Variable definitions - Macros - Template includes - etc.
  • 21. The syntax varies from tag to tag.
  • 22. Some are just a single word. ! {% requireLogin %}
  • 24. Some have a closing tag. ! {% block content %} <p>Hey</p> {% endblock %}
  • 25. Some even have nested tags. ! {% if foo %} <p>Something</p> {% else %} <p>Something else</p> {% endif %}
  • 26. It really all depends on the tag. ! The only thing they have in common is that they all start with “{%”, followed by the tag name. ! {% tagname ...
  • 27. Twig comes with several built-in tags. ! {% autoescape %} {% block %} {% filter %} {% do %} {% embed %} {% extends %} {% autoescape %} {% flush %} {% for %} {% from %} {% if %} {% import %} {% include %} {% macro %} {% sandbox %} {% set %} {% spaceless %} {% use %} {% verbatim %}
  • 28. {% autoescape %} ! Escapes text for HTML. ! {% autoescape %} <p>Hey</p> {% endautoescape %} => &lt;p&gt;Hey&lt;/p&gt;
  • 29. {% autoescape %} (Cont.) ! ...or Javascript ! {% autoescape "js" %} http://foo.com {% endautoescape %} => httpx3Ax2Fx2Ffoo.com
  • 30. {% spaceless %} ! Removes any whitespace between Twig/HTML tags. ! {%- spaceless %} <p>Hey there</p> {% endspaceless -%} => <p>Hey there</p>
  • 31. {% verbatim %} ! Defines template code that Twig should output as-is, without parsing. ! {% verbatim %} <p>Type “{{ foo }}”.</p> {% endverbatim %} => <p>Type “{{ foo }}”.</p>
  • 32. You never put a Twig tag inside another Twig tag. ! Bad: ! {{ "Hey {{ firstName }}" }} ! Good: ! {{ "Hey " ~ firstName }}
  • 34. Twig supports five different types of values. ! Strings: "Hey" / 'Hey' Numbers: 42 / 3.14 Booleans: true / false Arrays: ['a', 'b', 'c'] Objects: { foo: 'bar' }
  • 35. An expression is either a solo value, or multiple values combined to form another value. ! "Hey" => "Hey" "Hey "~"there" => "Hey there" 10 => 10 true => true ['a','b','c'] => ['a','b','c'] "Day "~1 => "Day 1" 10*(5+5) => 100
  • 36. Variables are values that get set to a name, to be referenced later. ! Use the {% set %} tag to create them. ! {% set foo = "foo" %} {% set a = 42 %} {% set foobar = foo~"bar" %}
  • 37. The {% set %} tag can also be used as a tag pair. ! {% set foo %} <p>foo</p> {% endset %} ! That’s the same as: ! {% set foo = "n <p>foo</p>n " %}
  • 38. Variables are one tool for keeping our templates DRY. ! {% set title = "About Us" %} ... <title>{{ title }}</title> ... <h1>{{ title }}</h1>
  • 40. Filters modify values. ! They can uppercase text, merge arrays, and lots of other things.
  • 41. To pass a value through a filter, type a pipe (“|”) after the value, followed by the filter name. ! "foo"|upper => "FOO" 21.3|round => 21 ['a','b','c']|length => 3
  • 43. You can even chain them. ! "foobar"|slice(0,3)|upper => FOO
  • 44. You can add filters to variables, too. ! {% set foo = "foo" %} {{ foo|length }} => 3
  • 45. You can use them in pretty much any context you can think of. ! {{ value|filter }} ! {% set foo = value|filter %} ! {% do func(value|filter) %}
  • 46. Filters only modify the value directly before the filter. ! "foo"~"bar"|upper => fooBAR ! ("foo"~"bar")|upper => FOOBAR
  • 47. Twig comes with tons of built-in filters: |abs |batch |capitalize |covert_encoding |date |date_modify |default |escape |first |format |join |json_encode |keys |last |length |lower |nl2br |number_format |merge |upper |raw |replace |reverse |round |slice |sort |split |striptags |title |trim |url_encode
  • 48. |length ! Finds the length of a string or array. ! {{ "foobar"|length }} => 6 ! {{ [1, 2, 3]|length }} => 3
  • 49. |upper & |lower ! Modify the casing of a string. ! {{ "foo"|upper }} => FOO ! {{ "BAR"|lower }} => bar
  • 50. |raw ! Protects a string from getting escaped. ! {{ "<p>Hey</p>" }} => &lt;p&gt;Hey&lt;/&gt; ! {{ "<p>Hey</p>"|raw }} => <p>Hey</p>
  • 51. |date ! Formats a date. ! {{ now|date("F j, Y") }} => April 23, 2014
  • 53. Functions perform functions. ! To call one, type its name, followed by parentheses. ! {{ parent() }}
  • 55. Some of them are global: ! {{ dump(foo) }} ! And they can also be nested within objects: ! {{ craft.isLocalized() }}
  • 56. Twig comes with a few global functions built-in: attribute() block() constant() cycle() date() dump() include() max() min() parent() random() range() source() template_from_string()
  • 57. min() & max() ! Returns the smallest/largest value in a given array. ! {{ min([1, 2, 3]) }} => 1 ! {{ max([1, 2, 3]) }} => 3
  • 58. random() ! {{ random("foobar") }} => f/o/b/a/r ! {{ random([1, 2, 3]) }} => 1/2/3 ! {{ random(10) }} => 1/2/3/4/5/6/7/8/9/10
  • 59. range() ! Creates a range of numbers as an array. ! {% set r = range(1, 5) %} => [1, 2, 3, 4, 5] ! {% set r = [1..5] %} => [1, 2, 3, 4, 5]
  • 60. dump() ! Outputs information about a given variable. Helpful when debugging. ! {{ dump(foo) }} ! (In Craft, dump() is only available in Dev Mode.)
  • 62. You can prevent certain parts of your template from executing unless a certain condition is met by wrapping it in conditional tags.
  • 63. Conditionals always open with an {% if %} tag, and close with an {% endif %} tag. ! {% if user %} <p>Hey there handsome!</p> {% endif %}
  • 64. You can also specify template code to be executed if the condition doesn’t pass, using the {% else %} tag. ! {% if user %} <p>Hey there handsome!</p> {% else %} <p>Have we met?</p> {% endif %}
  • 65. There’s also an {% elseif %} tag if you need fallback conditions. ! {% if user %} <p>Hey there handsome!</p> {% elseif username %} <p>Is this {{ username }}?</p> {% else %} <p>Have we met?</p> {% endif %}
  • 66. Conditionals can be nested. ! {% if user %} {% if user.male %} <p>Hey there handsome!</p> {% else %} <p>Hey pretty lady!</p> {% endif %} {% elseif username %} <p>Is this {{ username }}?</p> {% else %} <p>Have we met?</p> {% endif %}
  • 67. A single condition can be made up of multiple expressions joined together with “and” or “or”. ! {% if foo and bar %} ! {% if foo or bar %}
  • 68. You can negate a condition by typing “not” before it. ! {% if not foo %}
  • 69. You can also group expressions together using parentheses. ! {% if foo and ( foo == "foo" or foo == "bar" ) %}
  • 70. Tests
  • 71. Tests are little conditional helpers. They don’t have to be used within conditionals, but usually are.
  • 72. To write a test, add either “is” or “is not” after a variable, followed by the test name. ! {% if foo is defined %} ! {% if foo is not empty %}
  • 73. Twig comes with a few tests built-in. ! is constant is defined is divisible by is empty is even is iterable is null is odd is same as
  • 74. is defined ! Tests whether a variable exists at all, without Twig getting mad at you if it’s not. ! {% if foo is defined %}
  • 75. is divisible by ! Tests whether a number is divisible by another. ! {% if 5 is divisible by(2) %} ! That’s similar to writing: ! {% if 5 % 2 == 0 %}
  • 76. is even & is odd ! Tests whether a number is even/odd. ! {% if 5 is even %} ! {% if 5 is odd %}
  • 77. is empty ! Tests whether a variable is “empty”. ! {% if foo is not empty %} ! That’s the same as writing: ! {% if foo %}
  • 78. is same as ! Tests whether two variables have the same *type*. ! {% if 5 == "5" %} => true ! {% if 5 is same as "5" %} => false
  • 80. Arrays and objects both contain multiple values.
  • 81. Arrays contain values in a specific order, and have an inherent numerical index. ! {% set arr = ['a','b','c'] %} ! {{ arr[0] }} => 'a' {{ arr[1] }} => 'b' {{ arr[2] }} => 'c'
  • 82. Objects contain key-value pairs, and the order is generally less important. ! {% set obj = { foo: "Foo", bar: "Bar" } %} ! {{ obj.foo }} => "Foo" {{ obj.bar }} => "Bar"
  • 83. You can merge arrays together with the ‘merge’ filter. ! {% set a1 = ['a','b'] %} {% set a2 = ['c','d'] %} {% set a3 = a1|merge(a2) %} ! => ['a','b','c','d']
  • 84. You can merge objects together too. ! {% set o1 = {foo: "Foo"} %} {% set o2 = {bar: "Bar"} %} {% set o3 = o1|merge(o2) %} ! => {foo: "Foo", bar: "Bar"}
  • 85. You can grab part of an array with the “slice” filter. ! {% set a1 = ['a','b','c'] %} {% set a2 = a1|slice(0, 2) %} ! => ['a','b'] ! A shortcut is also available: ! {% set a2 = a1[0:2] %}
  • 87. You can loop through arrays with the {% for %} tag. ! The syntax is: ! {% for itemname in myarray %} ... {% endfor %} ! The 2nd param (“itemname”) is whatever you want to call each item within the array.
  • 88. Example 1: Age field ! <select name="age"> {% for age in [0..150] %} <option> {{ age }}</option> {% endfor %} </select>
  • 89. Example 2: Exp. Year field ! {% set y1 = now.year %} {% set y2 = y1 + 10 %} ! <select name="exp_year"> {% for year in [y1..y2] %} <option> {{ year }}</option> {% endfor %} </select>
  • 90. Example 3: Navigation ! {% set nav = [ { title: "Home", uri: "" }, { title: "About", uri: "about" } ] %} ! <nav> {% for item in nav %} <a href="{{ url(item.uri) }}"> {{ item.title }}</a> {% endfor %} </nav>
  • 93. Templates can include others. Include Template Parent Template Parent Template
  • 94. Use the {% include %} tag to include another template wherever the tag is placed. ! {% include "some/template" %}
  • 95. By default, any variables available to the “parent” template will also be available in the included template. ! {% set foo = "foo" %} {% include "myinclude" %} ! myinclude.html: {{ foo }} => foo
  • 96. You can define additional variables just for the included template using the “with” param. ! {% include "myinclude" with { foo: "foo" } %} ! some/template.html: {{ foo }} => foo
  • 97. To *only* pass certain variables to the included template, use the “only” param. ! {% set foo = "foo" %} {% include "myinclude" with { bar: "bar" } only %} ! some/template.html: {% if foo is defined %} => false
  • 99. A template can extend another, overriding parts of it (called “blocks”). Parent Template Block Child Template Child Template
  • 100. Define overridable areas in the parent template using the {% block %} tag. ! <body> {% block body %} <p>Default content</p> {% endblock %} </body>
  • 101. Use the {% extends %} tag within your child template to tell it which template it extends. ! {% extends "layout" %}
  • 102. Override the parent’s blocks by creating new blocks in the child template with the same name. ! {% extends "layout" %} ! {% block body %} <p>Override content</p> {% endblock %}
  • 103. You can output the parent block’s content using the parent() function. ! {% extends "layout" %} ! {% block body %} {{ parent() }} <p>Additional content</p> {% endblock %}
  • 106. Twig also lets you “embed” other templates, which is similar to including them, except you get to override the child template’s blocks in the process.
  • 107.
  • 108. Use the {% embed %} tag to embed another template. ! {% embed "promo" %} {% block body %} {{ parent() }} <span class="ribbon"> 50% off! </span> {% endblock %} {% endembed %}
  • 109. Macros
  • 110. Macros are like includes that are defined right within another template.
  • 111. Use the {% macro %} tag to define them. ! {% macro errors(list) %} {% if list|length %} <ul class="errors"> {% for error in list %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} {% endmacro %}
  • 112. You must import macros before you can use them, with either {% from %} or {% import %}. ! {% from _self import errors %} {{ errors(entry.allErrors) }} ! ! {% import _self as m %} {{ m.errors(entry.allErrors) }}
  • 113. You can import macros from other templates, too. ! {% from "macros" import errors %} {{ errors(entry.allErrors) }} ! ! {% import "macros" as m %} {{ m.errors(entry.allErrors) }} !