SlideShare a Scribd company logo
1 of 114
Download to read offline
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

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 Enginedrubb
 
Drupal 8 templating with twig
Drupal 8 templating with twigDrupal 8 templating with twig
Drupal 8 templating with twigTaras Omelianenko
 
Drupal 8: Theming
Drupal 8: ThemingDrupal 8: Theming
Drupal 8: Themingdrubb
 
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 & Drupallucenerevolution
 
Single Page Applications in Drupal
Single Page Applications in DrupalSingle Page Applications in Drupal
Single Page Applications in DrupalChris Tankersley
 
Drupal 8: Entities
Drupal 8: EntitiesDrupal 8: Entities
Drupal 8: Entitiesdrubb
 
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 2015Dropsolid
 
Intro to Apache Solr for Drupal
Intro to Apache Solr for DrupalIntro to Apache Solr for Drupal
Intro to Apache Solr for DrupalChris 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 8Anne 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 + DockerRoald 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 8Brian Ward
 

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

Template Toolkit
Template ToolkitTemplate Toolkit
Template Toolkitdwm042
 
Asp.Net MVC - Razor Syntax
Asp.Net MVC - Razor SyntaxAsp.Net MVC - Razor Syntax
Asp.Net MVC - Razor SyntaxRenier Serven
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentationbryanbibat
 
Jekyll - Liquid for noobs
Jekyll - Liquid for noobsJekyll - Liquid for noobs
Jekyll - Liquid for noobsBruno Mendes
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern PerlDave Cross
 
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 PHPStephan Schmidt
 
My First Rails Plugin - Usertext
My First Rails Plugin - UsertextMy First Rails Plugin - Usertext
My First Rails Plugin - Usertextfrankieroberto
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersJames Gray
 
course slides -- powerpoint
course slides -- powerpointcourse slides -- powerpoint
course slides -- powerpointwebhostingguy
 
Let's write a PDF file
Let's write a PDF fileLet's write a PDF file
Let's write a PDF fileAnge Albertini
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Gheyath 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

5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 

Recently uploaded (20)

5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.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) }} !