Symfony 4, (further in the text – Symfony) for templating provides twig bundle, which is a very useful templating engine. It is built by SensioLabs – the company behind Symfony. Besides Symfony, there are more platforms supporting Twig such as Drupal8, eZPublish, phpBB, Piwik, OroCRM, etc. In this article we will cover the basics and show how to extend them. Twig is by default not installed with Symfony, you need to include symfony/twig-bundle with the composer (composer require symfony/twig-bundle).
Features
Twig has a lot of built-in features separated into groups, which can be divided into operators, functions, tags, filters, and tests. A lot of things can be done with built-in features, however, it is also possible to extend twig’s functionality. Templates should have “.html.twig” extension and they can be reused.
Templates
Templates are located inside templates folder, bundles are located inside [Bundle root]/Resources/views. Every template should have “.html.twig” extension and they can be reused (by including and extending). You can’t mix PHP code in templates, that’s okay because you don’t really need to mix it. If you can’t do something, you can always extend it with filter or function which will do exactly what you need. The template is a mix between HTML and twig special syntax, which is great because it forces developers to separate complicated logic and data layer from templates, which should be in controllers and models.
Personally, I really like the separation because I have found too much logic (loading collections, getting DB connections and DB queries, curl on external service, etc) in Magento templates over the years. It gets overly complicated because it allows anything, unlike templating with Twig.
Speed
All twig templates are compiled in PHP code and cached. Recompile will only happen when a cache is cleared from the console, or automatically in developer (dev) mode when twig file is changed. This is why twig templates are really fast to output HTML.
Show me the syntax
Twig has a special syntax that can be separated in:
{{ }} – prints something, functions returned values, variables, etc
{% %} – does something, it’s used for logic
{# #} – comment something, it’s equivalent to /**/ in PHP and it’s not rendered
It is good to know about feature groups (functions, tags, filters, etc.) which use special syntax.
Tags
They are used to control logic of the template, you can check full list on official documentation:
https://twig.symfony.com/doc/2.x/tags/index.html
There are a couple of examples with explanations on how they’re used.
“if”
Equivalent to “if” statement in PHP, used to check if statement match, you can combine it with “not” for the opposite. Example:
{% if inchoo == true %}
We are Inchoo
{% endif %}
Official documentation: https://twig.symfony.com/doc/2.x/tags/if.html
“for”
Is equal to “for” and “foreach” PHP loops, all in one tag. Official documentation can be found on:
https://twig.symfony.com/doc/2.x/tags/for.html
-foreach example:
{% for user in users %}
Username: {{ user.username }}
{% endfor %}
-for example (iterate between 0 and 10):
{% for i in 0..10 %}
{{ i }}
{% endfor %}
“extends”
Used to extend a template from another one, for example, you can create a base template for multiple pages and extend it to reuse structure. The best part is that you can change block from the extended template.
Documentation: https://twig.symfony.com/doc/2.x/tags/extends.html
-example:
base.html.twig
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Base title{% endblock %}</title>
</head>
<body>
<div id="content">{% block content %}Base content{% endblock %}</div>
</body>
</html>
test.html.twig
{% extends "base.html.twig" %}
{% block title %}Welcome to Inchoo{% endblock %}
{% block content %}
<h1>Hi</h1>
<p>We are Inchoo, agency from Croatia.</p>
{% endblock %}
output for the test will consist of base HTML structure with changed title and content div.
“Include”
It will import another template content inside template called import tag. The included template has access to all variables as a template called include. If the template doesn’t exist it will throw an exception.
Documentation: https://twig.symfony.com/doc/2.x/tags/include.html
-example:
{% include 'test.html.twig' %}
Filters
They are used to modify content before rendering, the most common filters are built in, but it is possible to extend them. A full list can be found in the official documentation: https://twig.symfony.com/doc/2.x/filters/index.html
Here is an example of the uppercase filter. The filter is called “upper”, and it’s piped (character “|”) with value. It’s used like this:
{{ ‘inchoo’ | upper }}
The example above will print INCHOO.
Functions
Twig function can be easily compared with PHP function, they are a block of statements that will do some logic and be repeatedly used. They can have parameters, depending on functionality, but they are used to couple some logic in one place and use it as many times as you want.
Calling functions
They are called inside double curly brackets (“{{}}”), you can check built in function on link https://twig.symfony.com/doc/2.x/functions/index.html.
-example:
{{ dump(data) }}
Operators
Similar to PHP twig support variety of operators. Operators are case sensitive, so be careful when using them. Some of operators are “in”, “not in”, “is”, Math (+, -, /, %, //, *, **), logic (and, or, not, (), b-and, b-xor, b-or), comparison (==, !=, <, >, >=, <=, ===, starts with, ends with, matches) and many more.
How to use operators
They must be inside “{% %}” logic syntax, but you can also combine them.
-Example “is in”:
{% if inchoo is in someArray %}
Tests
They are used to test if something is a match and you combine them with logical statements.
Documentation: https://twig.symfony.com/doc/2.x/tests/index.html
-Example:
{% if inchoo is defined %}
Yes, Inchoo is defined!
{% endif %}
Conclusion
Twig is a very powerful templating engine, I really enjoy using it. In comparison with other similar templating engines, it’s one of the best. I have used many of them over the years such as Smarty, Magento 1 and 2 layout system, Shopify Liquid, Laravel Blade. The learning curve is fast and it’s really easy to use for both frontend and backend developers. Since it has the extending functionality, you can do almost anything!