SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
These are the slides for a workshop I’ve given at a couple conferences, explaining how Twig works to people who don’t necessarily come from a programming background.
These are the slides for a workshop I’ve given at a couple conferences, explaining how Twig works to people who don’t necessarily come from a programming background.
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.
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 -->
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 %}
=> <p>Hey</p>
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
42.
Some accept arguments.
!
"foobar"|slice(0,3)
=> foo
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
53.
Functions perform functions.
!
To call one, type its name,
followed by parentheses.
!
{{ parent() }}
54.
Many functions accept
arguments:
!
random(1, 10)
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
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"
) %}
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.
Use the {% embed %} tag to
embed another template.
!
{% embed "promo" %}
{% block body %}
{{ parent() }}
<span class="ribbon">
50% off!
</span>
{% endblock %}
{% endembed %}
109.
Macros are like includes that
are defined right within
another template.
110.
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 %}
111.
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) }}
112.
You can import macros from other
templates, too.
!
{% from "macros" import errors %}
{{ errors(entry.allErrors) }}
!
!
{% import "macros" as m %}
{{ m.errors(entry.allErrors) }}
!