Twig Templates
Twig is the default templating engine for Symfony views. Rather than mixing raw
PHP into your HTML, Twig gives you a clean, compact syntax purpose-built for templates. The single
biggest reason to prefer it over plain PHP for views is safety: Twig auto-escapes
every variable it prints by default, so output is HTML-escaped automatically and cross-site
scripting (XSS) is prevented out of the box. You have to explicitly opt out with the |raw
filter if you really want unescaped output — the safe behavior is the default, not something you
have to remember to add.
Basic Twig Syntax
Twig has three kinds of delimiters, each with a distinct job:
| Syntax | Purpose |
|---|---|
{{ variable }} | Prints a variable's value — output is auto-escaped |
{% if %} ... {% endif %} | Control structures such as conditionals |
{% for item in items %} ... {% endfor %} | Loops over an array or collection |
{% extends 'base.html.twig' %} | Template inheritance — reuse a parent layout |
{% block content %} ... {% endblock %} | Defines a named block a child template can override |
{{ }} and {% %} delimiters are Twig's own syntax, unrelated to PHP tags.A Worked Example: show.html.twig
Recall the minimal controller from the Controllers page —
it called $this->render('article/show.html.twig', ['id' => $id]). That second
argument is an array of variables handed to the template. Here's a template that could receive
data like that (imagine the controller also passing an article object and a list of
tags):
{% extends 'base.html.twig' %}
{% block content %}
<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
{% if tags is not empty %}
<ul>
{% for tag in tags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
{% else %}
<p>No tags for this article.</p>
{% endif %}
{% endblock %}
This template extends a shared base.html.twig layout and only fills in the
content block — the surrounding HTML (head, navigation, footer) lives once in the
parent template instead of being repeated on every page.
Twig Filters
Filters transform a value before it's printed, using the pipe (|) syntax. They're
handy for formatting data without writing PHP logic inside the template.
{{ name|upper }}
{{ price|number_format(2) }}
name|upper prints the name variable converted to uppercase.
price|number_format(2) formats a numeric price value to two decimal
places, exactly like PHP's number_format() function — Twig ships with a large
library of built-in filters for strings, numbers, arrays, and dates.