Twig: Введение

Другие статьи серии Twig

В Drupal 8 на замену PHPTemplate пришел шаблонизатор Twig - "компилирующий обработчик шаблонов с открытым исходным кодом, написанный на языке программирования PHP. Armin Ronacher написал Twig в 2008 году для платформы блогов Chyrp. Он больше не возвращался к разработке и в большей степени занимался разработкой на Python. Синтаксис языка шаблонов Twig берёт начало от движков шаблонов Jinja и Django, первый из которых также создан Ронакером. Идею данного шаблонизатора развивает и поддерживает Fabien Potencier, ведущий разработчик и идеолог фреймворка Symfony, в котором Twig используется по умолчанию." (https://ru.wikipedia.org/wiki/Twig).

Все Twig шаблоны в Drupal 8 компилируются в php файлы и хранятся в каталоге sites/default/files/php/twig/. Файлы шаблонов при этом кешируются для повторного использования и перекомпилируются только при очистке Twig кеша.

Все шаблоны в модулях и темах должны находиться в каталоге /templates.

Почему Twig? Во-первых, он более безопасный. В шаблонах Drupal 7 часто выводились неочищенные данные и это в принципе понятно, так как верстальщик не должен следить за работой программиста, который банально мог забыть пропустить данные из форм через check_plain(). В шаблонах же Drupal 8 переменные будут по-умолчанию экранироваться. Кроме этого многие наверняка в шаблонах наблюдали Sql запросы и прочие изыски логики приложения, но в Twig шаблонах это будет исключено.

Во-вторых, в Twig есть очень интересная особенность - наследование шаблонов. Теперь достаточно создать базовый родительский шаблон и затем при создании дочернего шаблона в теге extends указать родительский шаблон. К примеру чтобы создать дочерний шаблон ноды нужно в нем прописать:


{% extends "node.html.twig" %}

Рассмотрим наследование на примере шаблонов для блока. Базовый родительский шаблон для блока block.html.twig содержит примерно такой код


<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    <div {{content_attributes.addClass('content') }}>
      {{ content }}
    </div>
  {% endblock %}
</div>

При этом содержимое тега block можно в дочернем шаблоне переписать. Рассмотрим код шаблона для блока с формой поиска block--search-form-block.html.twig

{% extends "block.html.twig" %}
{% block content %}
  <div{{ content_attributes.addClass('content', 'container-inline') }}>
    {{ parent() }}
  </div>
{% endblock %}

Дочерний шаблон будет содержать всю разметку block.html.twig за исключением переписанного содержимого внутри тега block:


{% block content %}{% endblock %}

Рассмотрим основные отличия PHPTemplate и Twig на примерах

Именование файлов шаблонов и функций

PHPTemplate файл шаблона: node--article.tpl.php
Twig файл шаблона: node--article.html.twig

Большинство theme_ функций сейчас вынесено в шаблоны (огромный плюс)
PHPTemplate функция: theme_node_links()
Twig файл шаблона: node-links.html.twig

Docblock и комментарии

Docblock в PHPTemplate:

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

Twig:

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

Комментарии вместо стандартных php комментариев теперь выглядят так:


{# Twig комментарий #} 

Работа с переменными

Вывод переменных:

PHPTemplate:


<div class="content"><?php print $content; ?></div>

Twig:


<div class="content">{{ content }}</div>

Вывод свойств объектов и элементов массивов:

PHPTemplate:


<?php print $content->body; ?>

Twig:


{{ content.body }}

Вывод элементов массива с хешем в имени ключа

PHPTemplate:


<?php print $item['#item']['alt']; ?>

Twig:


{{ item['#item'].alt }}

Запись в переменную:

PHPTemplate:


<?php $image = $content->field_image; ?>

Twig:


{% set image = content.field_image %}

Запись в переменную массива:

PHPTemplate:


<?php $classes = array('class1', 'class2', 'class3'); ?>

Twig:


{% set classes = ['class1', 'class2', 'class3'] %}

Условия

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 %}

Циклы

PHPTemplate:


<?php foreach ($users as $user) {} ?>

Twig:


{% for user in users %} {% endfor %}

Управление пробелами

Twig позволяет убирать пробелы из вывода с помощью символа - в начале и/или конце структуры {{ }} для вывода переменных.

И в начале, и в конце:


<div class="body">
  {{- block.content -}}
</div>
{#
Результат:
<div class="body">контент</div>
#}

Только в начале:


<div class="body">
  {{- block.content }}
</div>
{#
Результат:
<div class="body">контент
</div>
#}

Только в конце:


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

{# Результат:
<div class="body">
контент</div>
#}

Официальная документация по Twig в Drupal 8 https://www.drupal.org/theme-guide/8/twig