Symfony for frontend developers #2 – Twig templates

This article is part of a series; see Symfony for frontend developers for more.

Introduction

Symfony projects don’t have to use the Twig templating language, but it’s very useful.  We use it on all our Symfony2 projects here at White October.

If you’re a frontend developer, Twig will be both a blessing and a curse.  It’ll be a curse, because at first it will seem like one more weird Symfony2 thing for you to learn, but persevere and it’ll be a blessing – you’ll soon appreciate its power and clean syntax!

The reason Twig is included in this series is because if a backend developer asks you to add styling and markup up to a page on a Symfony site, the unstyled page they give you will probably make use of Twig.

This blog post summarises some of the most important parts of Twig for someone who’s styling a Symfony site, and answers some questions about Twig from a frontend perspective.  But if you like the look of Twig, you should definitely take 10 minutes to read the official documentation’s Twig for template designers section – it covers the whole of Twig very succinctly and neatly.

Two ways to think about it

So, what is Twig?  Well, there are two ways to think about it:

1. Twig is inline PHP made nice

If you were involved in web development a few years ago, you’ll probably have seen plenty of files which mixed PHP code and HTML together.  This gives a lot of expressive power, but it’s messy and hard to maintain.  You can think of Twig as inline PHP made nicer!

One advantage of this way of thinking is that it is quite accurate – Twig templates do in fact compile down to a mix of HTML and PHP.  However, I actually find the second way of thinking more helpful day-to-day:

2. Twig is HTML plus some useful magic

This article is aimed at frontend developers.  Therefore, I’m not going to cover the gnarly details of how Twig works.  But I will show you how to use it, and I will explain some of the “magic” so that you can work with it better!

The most important thing

The key thing to know when reading or writing Twig is that there are three special kinds of syntax:

  • {{ things in double curly-brackets }}

  • {% things surrounded by curly-brackets and percentage signs %}

  • {# and this bracket syntax which is used for comments #}

The basics of these are simple:

  • {{ this one }} prints the result of the expression in the brackets out to the template

  • {% this one %} is used for statements like loops, if/else etc

  • and, as mentioned, {# this one #} is for comments, which can spread over multiple lines if you want.

Output with {{ }}

As the list above says, you use double curly-brackets (aka “double braces”) to output the value of a variable or an expression into your template.

Here are some examples.  This isn’t an exhaustive list, but will give you an idea of the kind of things Twig can do:

This is pretty basic – it just outputs the variable small_print:

{{ small_print }}


Variables??
 A common issue encountered by frontend devs using Twig is not knowing where the values of the variables they’re using actually come from.  The next article in the series will cover this in detail, so don’t miss it!

There are some clever variants, called “filters”, which transform the output before printing:

{{ small_print | lower }}
{{ small_print | upper }}
{{ small_print | nl2br }} {# turns newlines into <br> tags #}
{{ small_print | escape }} {# escapes special characters which have a meaning in HTML #}
{{ small_print | e }} {# same as the one above #}
{{ small_print | escape(‘js’) }} {# escaping for javascript #}

(Other escape options are ‘css’, ‘url’ or ‘html_attr’).

See http://twig.sensiolabs.org/doc/filters/index.html for a full list of Twig filters – there are lots more!  (Note that some of the filters in the list I’ve linked to are designed for use when you’re doing more than simply outputting a variable.)  There are also a few more examples of filters later in this post.

What actually are variables?

Twig supports all kinds of variable types.  Consider these two examples:

{{ settings.smallPrint }}
{{ actions['help'] }}

With the statement settings.smallPrint, we’re referencing the “smallPrint” property of an object called “settings”.  (In technical terms, this “property” could actually be a field on the object, a method, or even a getter method called getName, and Twig would find it!  Clever, eh?)

The second example in the code block above includes the statement actions[‘help’].  This is an example of how you can retrieve a value from an array.  In fact, the dot syntax and the array syntax are interchangeable, but using one for objects and one for arrays does make things a bit clearer.

Control structures – {% %}

Let’s go back to those three types of syntax, and look at the use of {% %} for control structures.  If you’ve done any programming, the idea of control structures will be familiar to you, so I’ll just give a simple example.  If you’ve not done any programming, you can probably skip this section and leave the control structures to your backend developer!

Here’s an example of some of the most common and useful structures in Twig – if, elseif and for.  Notice the use of a new filter here — we’re using length to get the size of the users array.

 {% if users|length > 0 %}
   <ul>
       {% for user in users %}
           <li>{{ user.username }}</li>
       {% endfor %}
   </ul>
{% elseif users|length > 9 %}
   {# do something else #}
{% else %}
   {# do another something else #}
{% endif %}

For more detail about this sort of thing in Twig, check out the documentation.

Inheritance and blocks

Finally, let’s think about inheritance and blocks.  These can really reduce repetition in your HTML files, allowing you to easily reuse page layout and page fragments.

Here’s a simple HTML page skeleton with some Twig blocks in it.  You can call this file anything you like, but the examples which follow will assume that it’s called base.html.twig.

<!DOCTYPE html>
<html>
   <head>
       {% block head %}
           <link rel="stylesheet" href="style.css" />
           <title>Acme Inc - {% block title %}{% endblock %}</title>
       {% endblock %}
   </head>
   <body>
       <div id="content">{% block content %}{% endblock %}</div>
       <div id="footer">
           {% block footer %}
               &copy; Copyright {{ "now"|date("Y") }}.
           {% endblock %}
       </div>
   </body>
<html>

The block tag simply tells Twig that a “child” template may override those portions of the template.  Notice that blocks can have default content – they don’t have to be overridden.  (And did you notice the neat example of Twig’s date filter?)

Here’s a simple child template “filling in” those blocks (notice the extends tag):

{% extends "base.html.twig" %}
{% block title %}Index{% endblock %}
{% block head %}
   {{ parent() }}
   <style type="text/css">
   .special { color: red; }
   </style>
{% endblock %}
{% block content %}
   <p>
       Welcome to my awesome homepage.
   </p>
{% endblock %}

So you can have some very simple pages that just override small portions of their parent.  And you don’t have to keep repeating the same layout code over and over!  Inheritance is an excellent way to build up the basic structure of your site’s pages, helping keep things consistent.

Twig will take the parent template and the child template, combine them together and render it all to create the following:

<!DOCTYPE html>
<html>
   <head>
       <link rel="stylesheet" href="style.css" />
       <title>Acme Inc - Index</title>
       <style type="text/css">
           .special { color: red; }
       </style>
   </head>
   <body>
       <div id="content">
           <p>
               Welcome to my awesome homepage.
           </p>
       </div>
       <div id="footer">
           &copy; Copyright 2014
       </div>
   </body>
<html>

Notice how the head here contains everything from the parent template’s head section and from the child’s head block?  That’s thanks to the line {{ parent() }}.  This means “render whatever my parent template has in this block”, allowing you to combine the default content of a block with whatever you’re adding.

Includes

Includes are the other side of the coin from inheritance.  They allow you to embed the contents of one template into another, so are great for including the same fragment of text or HTML in multiple places:

{% include 'my-common-element.html.twig' %}

Further reading

This is only an overview, so I do encourage you again to read the official Twig docs.

The following are a few specific topics I left out of this blog post but which are also worth you following up once you’ve read the basic Twig docs:

Up next

As I mentioned, the next article in this series will help you unravel where Twig variables get their values.  Stay tuned!

Post a Comment

Your email address is never published nor shared. Required fields are marked *

Ready to talk?

Whether you want to create a new digital product or make an existing one even better, we'd love to talk it through.

Get in touch