Extending Twig Templates: Inheritance, Filters, and Functions

Share this article

When working within an MVC architecture, it’s common to use a template library to populate the dynamic content of our views. There are dozens of such libraries available for PHP, but Twig is one of the standouts because of the ability to extend core features with custom implementations. In this article we’ll explore how Twig templates can be extended using template inheritance, filters, and functions.

Limitations in Template Libraries

The most common limitation that many template libraries have is the inability to extend template features. For example, it’s common to include all of the references to CSS and JavaScript files in the header or footer section of a page, and so we create a header template and include that file in all of our pages. But what if we have a page which needs to initialize a Google map on page load? The JavaScript for the map should be only called from this one page, but many developers would needlessly include all of the JavaScript and CSS files in the one header. Another workaround is to include the common shared files in the header and include the other specific files inside the page templates as necessary. The header file might look like this:
<!DOCTYPE html>
<html>
 <head>
  <link rel="stylesheet" href="style.css">
  <script src="jQuery.js" type="text/javascript"></script>
 </head>
… and the map template might look like this:
<script src="googlemaps.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
    $("#google_map").google_map();
});
</script>
<div id="google_map"></div>
The common CSS and JavaScript are referenced in the header, and map-specific code is inside the page template. While this works, ideally we should keep all of these references in one place for consistency and cleaner code instead of split across files like this. With most template libraries, we have no option other than to go with the techniques above. But now let’s see what Twig offers to cope with this situation.

Extending Twig Templates

Twig gives us the ability to extend child templates from parent templates using inheritance. Probably the easiest way to see how inheritance works is with an example. The following code is a parent template:
<!DOCTYPE html>
<html>
 <head>
  {% block head %} Sample Content {% endblock %}
 </head>
 <body>
 </body>
</html>
We define blocks inside the parent template which have a name and some content inside it. Then we can extend the defined blocks inside child templates like so:
{% extends "parent.html" %}
{% block head %} Head 1 {% endblock %}
In the child, we extend the parent template by using the extend keyword followed by the template file name. We then redefine the head block to contain dynamically extended content. Omitting the head block in child template will cause the parent to use the content it already has defined as a default. Now that we have a basic idea of how inheritance works in Twig, let’s create a more complete page layout.
<!DOCTYPE html>
<html>
 <head>
  {% block head %}
  <link rel="stylesheet" href="style.css">
  <script src="jQuery.js" type="text/javascript"></script>
  {% endblock %}
 </head>
 <body>
  <div id="grid">{% block content %} {% endblock %}</div>
  <div id="info">{% block sidebar %} {% endblock %}</div>
  <div id="footer">
   {% block widget1 %} {% endblock %}
   {% block widget2 %} {% endblock %}
   {% block widget3 %} {% endblock %}
   {% block footer %}
   &copy; 2013 example.com
   {% endblock %}
  </div>
 </body>
</html>
I’ve created a main template which contains all of the components of a standard web page. There’s a header block where we can include files dynamically, a dynamic main content area, and an information sidebar. In the footer there’s three dynamic widgets followed by the copyright message. With other templating systems we might have to create headers, footers, content, and sidebars separately to reuse across multiple templates. But with Twig’s support of inheritance, we can create the one main template to use across all of the pages in our site. Let’s say we want a use the template for a page which relies on a specific jQuery plugin. Basically we need to include the plugin’ files which depend on the jQuery library we’ve already provided, so we would extend the template this way:
{% block head %}
{{ parent() }}
<script src="jquery.plugin.js"></script>
{% endblock %}
The head block is redefined to reference the custom plugin files, but also while preserving the contents of original head section. The parent() function is used to retrieve the original head content. Indeed, Twig templates are highly flexible and are able to cater any type of requirement. Blocks can be placed anywhere, and block content can be changed in various ways to suit our needs. Up until now we’ve only discussed how we can use template inheritance to extend our templates. Twig comes with a number of features to further extend templates; let’s look now at how filters and functions fit into the process.

Role of Twig Filters

Filters are used to modify variables inside a template. You can find a list of built-in filters in the Twig documentation, but to illustrate the concept I’ll show you the basic usage of a filter to remove leading and trailing whitespace from a value.
{{ "Varible content" | trim() }}
Built in filters are very useful, but the real power of filters come with the implementation of custom filters. Twig provides a well-defined method for creating our own filters. Since data grids are a common means of presenting data in a web app, let’s assume we have a grid that displays a product table with different categories. We’ve been asked to display the data with each category highlighted with a specific color. We can use a custom filter to implement this feature. New filters are created by using anonymous PHP functions and the Twig_SimpleFilter class.
<?php
$filter = new Twig_SimpleFilter("highlight", function ($key) {
    switch (trim($key)) {
        case "book_category":
            echo '<span class="books_color">';
            break;
        case "cd_category":
            echo '<span class="cd_color">';
            break;
        case "ebook_category":
            echo '<span class="ebook_color">';
            break;
        default:
            // nothing
    }
});
$twig->addFilter($filter);
I’ve created a new filter named “highlight”, and then added it to the Twig environment using the addFilter() method. A category will passed to the filter as a variable, and inside the function we switch the category and output an element with specific CSS class to generate the dynamic highlighting in the grid. We can use this filter inside our templates like so, with products as an array which consists of our product names and categories:
{% block content %}
 {% for product in products %}
  <div>
   {% filter highlight %}
   {{ product.category }}
   {% endfilter %}
   {{ product.product }}
   </span>
  </div>
 {% endfor %}  
{% endblock %}

Role of Twig Functions

Twig functions are used to add dynamic content to our templates. There’s a selection of built-in functions, but as with filters, the real power of function comes with the ability to create our own implementations.
<?php
$function = new Twig_SimpleFunction("function_name", function ($arg1, $arg2) {
    // implementation
});
$twig->addFunction($function);
Again we can use anonymous functions to create dynamic Twig functions. The first parameter to the Twig_SimpleFunction
class is the name of the function, and the second is the function definition. The function is added to the Twig environment using addFunction(). Let’s assume that we are using a library for working with form fields like textboxes, checkboxes, etc. Usually we just write the required HTML directly in the templates like so:
<input type="text" name="fname" class="chosen">
But if the library requires certain attributes to work it can be difficult to include the necessary HTML for every form without making any mistakes. We can create a Twig function to insert each of the field instead.
<?php
$function = new Twig_SimpleFunction("form_text", function ($name, $id, $value = "", $class = "form_text") {
    echo '<input type="text" name="'.$name.'" id="'.$id.'" value="'.$value.'" class="'.$class.'">";
});
$twig->addFunction($function);
This technique makes sure that we include the correct attributes without making mistakes. We would call this function from within our templates using the following:
{{ form_text("fname", "fname", "", "chosen") }}
Inheritance, filters, and functions are a powerful combination when it comes to extending Twig templates. We can use these in different ways to easily deal with the advanced requirements of our application.

Summary

The ability to create extensible templates allows us to reuse templates and features in multiple places throughout our applications when necessary, and Twig is one of best templating libraries when it comes to support for for extending the core library’s functionality. Twig also comes with extensive documentation explaining every aspect of the template creation process, which makes extending things easy. Let me know your experiences with Twig and your thoughts on its template extending process. I’m looking forward to hearing from you. Image via Fotolia

Frequently Asked Questions (FAQs) about Extending Twig Templates: Inheritance, Filters, and Functions

What is the concept of inheritance in Twig templates?

Inheritance in Twig templates is a powerful feature that allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override. This concept is similar to the inheritance in object-oriented programming. It helps to keep your code DRY (Don’t Repeat Yourself), making it easier to manage and maintain.

How can I create a custom filter in Twig?

Creating a custom filter in Twig involves defining a new filter function and registering it with Twig. This can be done in your project’s services configuration file. The filter function takes the input value as the first argument and any additional arguments after that. Once the filter is registered, you can use it in your Twig templates just like any built-in filter.

How can I extend a Twig template?

To extend a Twig template, you use the ‘extends’ tag. This tag tells Twig that the current template “extends” another template. When rendering the template, Twig will replace the blocks in the parent template with the blocks in the child template. This allows you to reuse common template parts while customizing the content.

What are Twig functions and how are they used?

Twig functions are used to generate content. They are called in your templates using the function name followed by parentheses. Some functions take arguments, which are passed inside the parentheses. Functions can do anything from generating URLs to performing complex calculations.

How can I include a template in another template?

You can include a template in another template using the ‘include’ tag. This tag allows you to render a template and include its output in another template. This is useful for things like headers and footers that are included in multiple templates.

How can I pass variables to a template?

Variables can be passed to a template by including them in the render function’s second argument. This argument should be an associative array where the keys are the variable names and the values are the variable values. These variables can then be accessed in the template using the variable name.

How can I control the whitespace in my Twig templates?

Twig provides several ways to control whitespace in your templates. You can use the ‘-‘ character at the start or end of a tag to trim whitespace. You can also use the ‘spaceless’ tag to remove all whitespace between HTML tags.

How can I debug a Twig template?

Twig provides a ‘dump’ function that you can use to output the value of a variable. This can be useful for debugging. You can also enable the debug mode in your Twig environment to get more detailed error messages.

How can I use a Twig filter in a template?

To use a filter in a Twig template, you use the ‘|’ character followed by the filter name. Some filters take arguments, which are passed in parentheses after the filter name. Filters are applied to the value before the filter.

How can I create a global variable in Twig?

Global variables in Twig can be created by adding them to the ‘globals’ option in your Twig environment configuration. Once a global variable is defined, it can be accessed in any template.

Rakhitha NimeshRakhitha Nimesh
View Author

Rakhitha Nimesh is a software engineer and writer from Sri Lanka. He likes to develop applications and write on latest technologies. He is available for freelance writing and WordPress development. You can read his latest book on Building Impressive Presentations with Impress.js. He is a regular contributor to 1stWebDesigner, Tuts+ network and SitePoint network. Make sure to follow him on Google+.

Advanced
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week