Previously we said that controllers accept request and return response. The response, however, can often be any content type. The production of actual content is something controllers delegate to the templating engine. The templating engine then has the capability to turn the response into HTML, JSON, XML, CSV, LaTeX, or any other text-based content type.
In the old days, programmers mixed PHP with HTML into the so called PHP templates (.php and .phtml). Though still used with some platforms, this kind of approach is considered insecure and lacking in many aspects. One of which was cramming business logic into template files.
To address these shortcomings, Symfony packs its own templating language called Twig. Unlike PHP, Twig is meant to strictly express presentation and not to thinker about program logic. We cannot execute any of the PHP code within the Twig. And the Twig code is nothing more than an HTML with a few special syntax types.
Twig defines three types of special syntax:
{{ ... }}: This outputs variable or the result of an expression to the template.{% ... %}: This tag controls the logic of the template (if and for loops, and others).{# ... #}: It is the equivalent of the PHP /* comment */ syntax. The Comments content isn't included in the rendered page.Filters are another nice feature of Twig. They act like chained method calls upon a variable value, modifying the content before it is outputted, as follows:
<h1>{{ title|upper }}</h1>
{{ filter upper }}
<h1>{{ title }}</h1>
{% endfilter %}
<h1>{{ title|lower|escape }}</h1>
{% filter lower|escape %}
<h1>{{ title }}</h1>
{% endfilter %}It also supports functions listed as follows:
{{ random(['phone', 'tablet', 'laptop']) }}The preceding random function call would return one random value from within the array. With all the built-in list of filters and functions, Twig also allows for writing our own if needed.
Similar to PHP class inheritance, Twig also supports template and layout inheritance. Let's take a quick look back at the the app/Resources/views/customer/index.html.twig file as follows:
{% extends 'base.html.twig' %}
{% block body %}
<h1>Customer list</h1>
…
{% endblock %}Here we see a customer index.html.twig template using the extends tag to extend a template from another one, in this case base.html.twig found in app/Resources/views/ directory with content as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets%}{% endblock %}
<link rel="icon" type="image/x-icon"href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts%}{% endblock %}
</body>
</html>Here we see several block tags: title, stylesheets, body, and javascripts. We can declare as many blocks as we want here and name them any way we like. This makes the extend tag a key to template inheritance. It tells the Twig to first evaluate the base template, which sets the layout and defines blocks, after which the child template like customer/index.html.twig fills in the content of these blocks.
Templates live in two locations:
app/Resources/views/bundle-directory/Resources/views/What this means is in order to render/extend app/Resources/views/base.html.twig we would use base.html.twig within our template file, and to render/extend app/Resources/views/customer/index.html.twig we would use the customer/index.html.twig path.
When used with templates that reside in bundles, we have to reference them slightly differently. In this case, the bundle:directory:filename string syntax is used. Take the FoggylineCatalogBundle:Product:index.html.twig path for example. This would be a full path to use one of the bundles template file. Here the FoggylineCatalogBundle is a bundle name, Product is a name of a directory within that bundle Resources/views directory, and index.html.twig is the name of the actual template within the Product directory.
Each template filename has two extensions that first specify the format and then the engine for that template; such as *.html.twig, *.html.php, and*.css.twig.
We will get into more details regarding these templates once we move onto building our app.