Last updated December 20, 2013. Created by alexrayu on February 16, 2013.
Edited by ursula, Cottser, peezy, Eronarn. Log in to edit this page.

This page compares PHPTemplate to Twig. The Twig effort is currently in progress, so there will be changes and additions to this doc.

For more information, see:

About Twig

Twig is a PHP-based compiled templating language. When your web page renders, the Twig engine takes the template and converts it into a 'compiled' PHP template which it stores in a protected directory in sites/default/files/php_storage/... The compilation is done once. Template files are cached for reuse and are recompiled on clearing the Twig cache.

The Drupal Twig initiative shares the same motivation as the Symfony initiative: to adopt a modern, powerful, OOP-based engine that will allow developers to concentrate on Drupal proper.

1. Docblock

PHPTemplate:

  <?php
 
/**
   * @file
   * File description
   */
 
?>

Twig:

  {#
  /**
   * @file
   * File description
   */
  #}

2. File and function names

PHPTemplate file: node--article.tpl.php
Twig file: node--article.html.twig

PHPTemplate function: theme_node_links()
Twig file: node-links.html.twig

3. Variables

Printing a variable:
PHPTemplate: <div class="content"><?php print $content; ?></div>
Twig: <div class="content">{{ content }}</div>

Printing a hash key item
PHPTemplate: <?php print $item['#item']['alt']; ?>
Twig: {{ item['#item'].alt }}

Assigning a variable:
PHPTemplate: <?php $custom_var = $content->comments; ?>
Twig: {% set custom_var = content.comments %}

Assigning an array:
PHPTemplate: <?php $args = array('!author' => $author, '!date' => $created); ?>
Twig: {% set args = {'!author': author, '!date': created} %}

4. Conditionals

PHPTemplate: <?php if ($content->comments): endif; ?>
Twig: {% if content.comments %} {% endif %}

PHPTemplate: <?php if (!empty($content->comments)): endif; ?>
Twig: {% if content.comments is not empty %} {% endif %}

PHPTemplate: <?php if (isset($content->comments)): endif; ?>
Twig: {% if content.comments is defined %} {% endif %}

PHPTemplate: <?php if ($count > 0): endif; ?>
Twig: {% if count > 0 %} {% endif %}

5. Control structures

PHPTemplate: <?php foreach ($users as $user) {} ?>
Twig: {% for user in users %} {% endfor %}

6. Filters

Check_plain:
PHPTemplate: <?php print check_plain($title); ?>
Twig: {{ title|striptags }}

Translate:
PHPTemplate: <?php print t('Home'); ?>
Twig: {{ 'Home'|t }}

Translate with substitutions:
PHPTemplate: <?php print t('Welcome, @username', array('@username' => $user->name)); ?>
Twig: {{ 'Welcome, @username'|t({ '@username': user.name }) }}
Drupal 8 Twig (with trans tag extension):

{% set username = user.name %}
{% trans %}
  Welcome, {{ username }}
{% endtrans %}

Implode a list:
PHPTemplate: <?php echo implode(', ', $usernames); ?>
Original Twig: {{ usernames | join(', ') }}
Drupal 8 Twig1: {{ usernames }}

Escape:
PHPTemplate: <?php echo check_plain($title); ?>
Original Twig: {{ title|e }}
Drupal 8 Twig2: {{ title }}

7. Whitespace control

Twig has whitespace control which allows for removing the whitespace used for structuring a template file.

<div class="body">
  {{- block.content -}}
</div>

Is same as:

<div class="body">{{ block.content }}</div>

Notes

  1. In this first example, we show how Twig will be responsible for flattening renderable structures (currently arrays, maybe soon also objects) into flat strings of HTML. Previously, it was up to the template file or preprocess function to do this. (jenlampton)
  2. In the second example, we show how Twig will also be responsible for sanitizing data. Previously it was up to the template file or preprocess function to handle this as well. This last change is a really big deal for anyone hoping to create a PHPTemplate theme for Drupal 8 - you'll need to sanitize your own data. Yes, all of it. (jenlampton)

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

This 'Implode a list' example is confusing:

PHPTemplate:

<?php
echo implode(', ', $usernames);
?>

Original Twig: {{ usernames | join(', ') }}
Drupal 8 Twig1: {{ usernames }}

The PHPTemplate example requires $usernames to be an array of strings. The same goes for the Original Twig example where "usernames" is an array of strings. The Drupal 8 Twig example on the other hand requires an array of renderable objects. This is actually the fundamental difference between Drupal 8 Twig and the original Twig. Drupal 8 Twig can "prints" both plain text and rederable arrays.

An other confusing aspect of this example is that one expects all three example to produce the same output, but it doesn't (by default). Take this example:

  {% set nubmers = [{'#markup': 'One'}, {'#markup':'Two'}, {'#markup':'Three'}] %}
  {{ numbers }}

The above suggests that items are printed separated by comma's. But (of course) the output is: OneTwoThree

-- Erik
Drupal trainer at Wizzlern

The hash key item example might change in the future - see: [#2160611: Provide {{ item.item.alt }} Twig syntax for getting data from $item['#item']['alt']]