Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

An Introduction to Twig Template Engine

Parent Feed: 

Twig is one such fairly new engine, built for PHP. An author of Twig claims that although PHP is considered a kind of template processor, over time the development of PHP itself, along with the options it gives, ventured away from what is expected from a modern template system. In comparison to using PHP itself as a template engine, Twig claims to offer improved conciseness, template oriented syntax, features, extensibility, documentation, security, error messages and speed.

Template Engines

Before venturing into Twig itself, let's cover a bit of theory. For theory on what a template engine or a template processor is, please refer to http://en.wikipedia.org/wiki/Template_processor

The definition from this article, based on consensus from primary literature:

A template processor (also known as a template engine or template parser) is a piece of software or a software component that is designed to combine one or more templates with a data model to produce one or more result documents.

There is also a separate but relevant article titled Web template systems which gives some additional illustrations and points and covers a general case of template engine use in the context of the Web.

About Twig

Twig is one such fairly new engine, built for PHP. An author of Twig claims that although PHP is considered a kind of template processor, over time the development of PHP itself, along with the options it gives, ventured away from what is expected from a modern template system. In comparison to using PHP itself as a template engine, Twig claims to offer improved conciseness, template oriented syntax, features, extensibility, documentation, security, error messages and speed.

Personally, my favorite is conciseness which is basically more streamlined and simplified syntax we can use by means of Twig when we output the content of data. This gives us the benefit of greater code readability and, as a consequence, maintainability.

The syntax of Twig is inspired by Jinja template languages and also looks very similar to Liquid template engine, a Ruby library.

Introductory How-to and Tutorial

Let's try Twig. I'll be following instructions on http://twig.sensiolabs.org/doc/intro.html#installation.

The version of PHP I have on a particular machine I'm using to review Twig is "5.5.3-1ubuntu2.6" which is high enough (minimal version of PHP needed is 5.2.4) so that I can immediately proceed to install Twig:

~/www$ mkdir twig_project
~/www$ cd twig_project
~/www/twig_project$ composer require "twig/twig:~1.0"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing twig/twig (v1.16.2)
    Downloading: 100%         

Writing lock file
Generating autoload files

Let's create a test index.php file with the following contents copied from basic Basic API Usage section from http://twig.sensiolabs.org/doc/intro.html:

 'Hello {{ name }}!',
);
$twig = new Twig_Environment($loader);

echo $twig->render('index', array('name' => 'Fabien'));

Visiting index.php triggers "Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW) in /[...]/www/twig_project/index.php on line 6".

Searching for others with the same error in this context doesn't yield any significant results on Google which leads me to conclude that this usage scenario doesn't work out of the box as such. The problem is a missing array keyword, which means we have to change the Twig_Loader_Array input parameter to "array( 'index' => 'Hello {{ name }}!' )" after which everything works OK and index.php outputs the following:

Hello Fabien! 

Let's explore the improvements of Twig compared to plain PHP further. To that end, I choose to follow http://twig.sensiolabs.org/doc/templates.html

We shall change our index.php to the following:

 false,
));

echo $twig->render('index.html', array('name' => 'Fabien'));

The cache is false by default, so there'll be no difference if we omit the whole configuration array as a second parameter. In high throughput production environment, you will probably need to enable, set and configure caching properly. Here is a useful blog post detailing issues that might be of concern at that point.

Also, we will add a template named index.html:



    
        My Webpage
    
    
        
        {{ name }}
    </body>
</html>

Now, when we run index.php in our browser, we get the following output:



    
        My Webpage
    
    
        
        Fabien
    </body>
</html>

At this point, the sky is the limit. :)

Let's update index.php again with a simulated article content, let's say we are building a minimalistic CMS or something similar and let's presume that we have loaded some array with all the related article content we need on some particular page:

 false,
));

echo $twig->render('index.html', array(
	"articles" => array (
		1 => array(
			"title" => "Article 1 title",
			"paragraphs" => array (
				1 => "First paragraph.",
				2 => "Second paragraph.",
				3 => "Third paragraph."
			),
			"footer" => array(
				1 => "Date: ",
				2 => "01/25/2014"
			)
		),
		2 => array(
			"title" => "Article 2 title",
			"paragraphs" => array (
				1 => "First paragraph.",
				2 => "Second paragraph.",
				3 => "Third paragraph."
			),
			"footer" => array(
				1 => "Date: ",
				2 => "02/25/2014"
			)
		)
	)
));

We modify our template, index.html, to simply look like this:




    Twig testing


    
    {% for article in articles %}
        

{{ article.title }}

{% for paragraph in article.paragraphs %}

{{ paragraph }}

{% endfor %}
{% for footer_element in article.footer %} {{ footer_element }} {% endfor %}

{% endfor %} </body> </html>

Running it outputs the following:




    Twig testing

Article 1 title

First paragraph.

Second paragraph.

Third paragraph.

Date: 01/25/2014

Article 2 title

First paragraph.

Second paragraph.

Third paragraph.

Date: 02/25/2014

This is all good, except for indentation inconsistencies between template and output. To compensate for them by manually deleting and inserting whitespaces in template itself would defeat the purpose of using a template engine to a certain extent, in terms of code readability. This particular issue probably has to do with whitespace artefacts coming out from Twig itself. The issue is present whether spaces or tabs are used. Perhaps playing with whitespace control might alleviate it, at the cost of more code in the template itself.

Conclusion

Indentation issues aside, heavy use of template engines in various SaaS systems like Shopify and Desk.com is contributing to their rising use and they are probably not going away any time soon. Templating as such has also found its use in CMS systems like Drupal 8. What these two scenarios have in common is the fact that you can give access to a template file to a person who only understands a little bit of HTML and still have him be able to modify system's HTML/CSS output in a practically safe manner, compared to letting hir mess with server side scripts or some obscure and delicate parts of CMS, perhaps with a theme layer of Drupal 7. This, along with many other features which templating provides, is what makes the usage of template engines such as Twig quite useful.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web