<?php
// define our vars (fixed or via calculations)
$title = 'testpage';
$userName = 'bramus';
$weatherToday = 'cloudy';
?><!doctype html>
<html>
<head>
<title><?php echo htmlentities($title); ?></title>
</head>
<body>
Hi there <?php echo htmlentities($userName); ?>, the weather today is <?php echo htmlentities($weatherToday); ?>.
</body>
</html>
.tpl
extension
{{
and }}
in the template, e.g. {{ firstName }}
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
Hi there {{ user }}, the weather today is {{ weather }}.
</body>
</html>
<?php
$title = 'testpage';
$userName = 'bramus';
$weatherToday = 'cloudy';
$tplContent = file_get_contents(__DIR__ . '/templates/main.tpl');
$tplContent = str_replace('{{ title }}', htmlentities($title), $tplContent);
$tplContent = str_replace('{{ user }}', htmlentities($userName), $tplContent);
$tplContent = str_replace('{{ weather }}', htmlentities($weatherToday), $tplContent);
echo $tplContent;
<?php
class Template {
private $content;
public function __construct($template = null) {
if($template) $this->loadTemplate($template);
}
public function loadTemplate($template) {
$this->content = file_get_contents($template);
}
public function render($data) {
foreach ($data as $key => $value) {
$this->content = str_replace(
'{{ '. $key .' }}', htmlentities($value),
$this->content
);
}
return $this->content;
}
}
// EOF
<?php
// includes & requires
require_once __DIR__ . '/includes/classes/template.php';
// define our vars (fixed or via calculations)
$title = 'testpage';
$userName = 'bramus';
$weatherToday = 'cloudy';
// load template
$tpl = new Template();
$tpl->loadTemplate(__DIR__ . '/templates/main.tpl');
// render template with our data
// @note The template class with automatically prevent XSS for us :-)
echo $tpl->render(array(
'title' => $title,
'user' => $userName,
'weather' => $weatherToday
));
// EOF
Template
class is very basic. Possible improvements:
if
structures in our templatesfor
and foreach
structures in our templatesucfirst
)Twig
folder from the .zip
into the includes/
folder of your project
require_once __DIR__ . '/includes/Twig/Autoloader.php';
Twig_Autoloader::register();
templates/
folder
$loader = new Twig_Loader_Filesystem(__DIR__ . '/templates');
$twig = new Twig_Environment($loader);
.tpl
files to .twig
.tpl
.twig
file hasn't changed
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
Hi there {{ user }}, the weather today is {{ weather }}.
</body>
</html>
// Assuming we've already included and bootstrapped Twig
$tpl = $twig->loadTemplate('main.twig');
echo $tpl->render(array(
'title' => $title,
'user' => $userName,
'weather' => $weatherToday
));
{#
and #}
inside your .twig
file.
{# I am a template comment! #}
⚑
|
followed by a filter in the template to modify a parameter before it is displayed
{{ firstname|upper }}
⚑ will render firstname
in uppercase.{{ firstname|upper|reverse }}
{{ firstname|slice(0,4) }}
⚑
escape
⚑ (aliased to e
)
raw
⚑ filter to show a variable unaltered
<p>The value of <em>title</em> is {{ title }}</p>
<p>{{ tagline|replace({'like':'love', 'Twig':'you'}) }}</p>
<p>Today: {{ curdate|date("d/m/Y") }}</p>
<p>{{ name|upper|reverse }}</p>
echo $tpl->render(array(
'title' => 'The title <script>alert("XSS?");</script>',
'tagline' => 'I like Twig',
'curdate' => new DateTime(),
'name' => 'Bramus'
));
Full list of filters: http://twig.sensiolabs.org/doc/filters/index.html
// define our vars (fixed or via calculations)
$greeting = 'Good afternoon';
$user = array(
'firstname' => 'Bramus',
'lastname' => 'Van Damme',
'city' => 'Vinkt'
);
// load template
$tpl = $twig->loadTemplate('main.twig');
// render template with our data
echo $tpl->render(array(
'greeting' => $greeting,
'user' => $user
));
{{ greeting }} {{ user.firstname }} {{ user.lastname }}.
How's the weather in {{ user.city }}?
$lecturers = array(
array(
'name' => 'Rogier van der Linde', 'city' => 'Ghent',
'courses' => array('Webtechnology', 'Webdesign & Usability', 'Webscripting 1', 'Webprogramming')
), array(
'name' => 'Kevin Picalausa', 'city' => 'Ghent',
'courses' => array('Webscripting 2', 'Webprogramming')
), array(
'name' => 'Davy De Winne', 'city' => 'Schellebelle',
'courses' => array('Webtechnology', 'Webdesign & Usability', 'Webscripting 2')
), array(
'name' => 'Joske Vermeulen'
)
);
echo $tpl->render(array(
'name' => 'Bramus Van Damme',
'colleagues' => $lecturers
));
for
⚑ and if
⚑ tags in your template
{% for colleague in colleagues %}
<h3>
{{ colleague.name }}
{% if colleague.city %}<em>({{ colleague.city }})</em>{% endif %}
</h3>
<div>
{% if colleague.courses %}
<p>You might know him from:</p>
<ul>
{% for course in colleague.courses %}
<li>{{ course }}</li>
{% endfor %}
</ul>
{% else %}
<p>(He's not teaching any web courses)</p>
{% endif %}
</div>
{% endfor %}
if
tag in Twig works just as any other if
{% if username == 'bramus' %} YOLO {% endif %}
{% if user in ['bramus', 'rogier'] %} YOLO {% endif %}
elseif
is also supported
{% if blogpost.visibility == 'password' %}
<p>Blogpost is password protected</p>
{% elseif blogpost.visibility == 'link' %}
<p>Blogpost is public for those who have the link</p>
{% else %}
<p>Blogpost is public for all</p>
{% endif %}
$courses
using for-else-endfor
⚑
echo $tpl->render(array(
'courses' => array(
'JPW235' => 'Webscripting1',
'JPW213' => 'Webscripting2',
'JPW218' => 'Web & Mobile',
)
);
<ul>
{% for val in courses %}
<li>{{ val }}</li>
{% else %}
<li>(array is empty)</li>
{% endfor %}
</ul>
<ul>
{% for k in courses|keys %}
<li>key: {{ k }}</li>
{% else %}
<li>(no items in the array)</li>
{% endfor %}
</ul>
<ul>
{% for key, val in courses %}
<li>{{ key }} = {{ val }}</li>
{% else %}
<li>(no items in the array)</li>
{% endfor %}
</ul>
loop
variable⚑ inside iterations:
<ul>
{% for val in courses %}
<li>
{{ val }}
<ul>
<li><code>loop.index</code>: {{ loop.index }}</li>
<li><code>loop.index0</code>: {{ loop.index0 }}</li>
<li><code>loop.revindex</code>: {{ loop.revindex }}</li>
<li><code>loop.revindex0</code>: {{ loop.revindex0 }}</li>
<li><code>loop.first</code>: {{ loop.first }}</li>
<li><code>loop.last</code>: {{ loop.last }}</li>
<li><code>loop.length</code>: {{ loop.length }}</li>
</ul>
</li>
{% endfor %}
</ul>
<p>{% for i in 0..10 %}{{ i }}{% endfor %}</p>
<p>{% for letter in 'a'..'z' %}{{ letter }}{% endfor %}</p>
$loader = new Twig_Loader_Filesystem(__DIR__ . '/templates');
$twig = new Twig_Environment($loader, array(
'cache' => __DIR__ . '/cache',
'auto_reload' => true // set to false on production
));
layout.twig
and extend it per page in your project<h1>{{ pageTitle }}</h1>
<main>
{% block pageContent %}
<p>This is the pageContent</p>
{% endblock %}
</main>
{% block pageFooter %}
<footer>This is the footer</footer>
{% endblock %}
main.twig
layout.twig
) using extends
⚑
{% extends 'layout.twig' %}
{% block pageContent %}
<p>Lorem ipsum dolor sit amet</p>
{% endblock %}
$tpl = $twig->loadTemplate('main.twig');
echo $tpl->render(array(
'pageTitle' => 'Template Inheritance'
));
set
⚑ in Twig
{% extends 'layout.twig' %}
{% set pageTitle = pageTitle|replace({'e': 'a'}) ~ ' (Manipulated)' %}
parent()
⚑
{% extends 'layout.twig' %}
{% block pageStyle %}
{{ parent() }}
footer { text-align: center; padding-top: 2em; }
{% endblock %}
parent()
Twig sports some other handy functionsif
, for
, block
and set
there are lots more tags available in TwigA code-only summary of this chapter is available at 08.templates.summary.html