Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll
18/11/2019, by Ivan

Если вы откроете файл шаблона page.html.twig темы Stable:

/core/themes/stable/templates/layout/page.html.twig

То вы обнаружите, что он отличается от шаблона Drupal 7 page.tpl.php, во-первых, расширением и во-вторых, обилием фигурных скобок {}. Это все из-за того что в Drupal 8 используется шаблонизатор Twig.

<main role="main">
    <a id="main-content" tabindex="-1"></a>{# link is in html.html.twig #}
 
    <div class="layout-content">
      {{ page.content }}
    </div>{# /.layout-content #}
 
    {% if page.sidebar_first %}
      <aside class="layout-sidebar-first" role="complementary">
        {{ page.sidebar_first }}
      </aside>
    {% endif %}
 
    {% if page.sidebar_second %}
      <aside class="layout-sidebar-second" role="complementary">
        {{ page.sidebar_second }}
      </aside>
    {% endif %}
 
 </main>

Новый шаблонизатор должен усмирить нерадивых Drupal разработчиков, включающих в шаблон различную логику, вплоть до MySQL запросов. В шаблоне twig нельзя использовать PHP, а значит придется использовать только средства Twig, а их более чем предостаточно для стилизации сайта.

Давайте разберемся как работать с Twig'ом.

Переменные в Twig

Если в PHP мы используем знак доллара $ для переменных, то в twig мы используем фигурные скобки:

{{ переменная }}

Таким образом мы записываем переменные две открывающиеся фигурные скобки, пробел, имя переменной, пробел, две закрывающиеся скобки. При этом нам не нужно использовать функцию print для распечатки переменной, нам совсем не нужно использовать PHP в шаблонах twig. Чтобы вывести переменную не нужно добавлять функцию print перед переменной twig, мы не используем PHP совсем в шаблонах twig, чтобы вывести переменную, нужно просто ее указать в двойных фигурных скобках.

Также удобно работать с переменными объектами и массивами, если раньше вам нужно было знать, что $node это объект, а $form это массив, то теперь все проще, мы обращаемся к свойствам переменных через точку:

{{ node.id }}

Мы можем также создавать переменные на лету:

{% set foo="bar" %}
 
Hi, here's my variable: {{ foo }}

Обратите внимание на синтаксис, что когда мы задаем переменную мы используем скобку со знаком процента, а когда выводим переменную, мы используем двойные скобки.

Мы можем задавать не только строки, но и массивы:

{%
  set foo_array = [
    'foo',
    'bar',
  ]
%}

Фильтры Twig

Хоть twig это не полноценный язык программирования, но он имеет набор инструментов для работы с данными. Наверно самым главным таким инструментом являются фильтры. Фильтры указываются через знак pipe |

{{ variable|filter }}

Фильтры позволяют изменять вывод переменных, например:

{{ node.title|length }} - выводит число длину строки
{{ node.title|uppercase }} - выводит строку в верхнем регистре
{{ node.title|lowercase }} - выводить строку в нижнем регистре 

Полный список фильтров Twig смотрите в этой статье (ссылка на статью по фильтрам) или в официальной документации по Twig http://twig.sensiolabs.org/doc/filters/index.html

Фильтры для Twig от Drupal

Друпал также добавляет свои фильтры в Twig, например фильтры для перевода строк. Если раньше мы использовали функцию t(), которая была реализована на PHP, а сейчас мы не можем использовать PHP код в Twig, значит нам нужен инструмент заменяющий функцию t().

Найти адекватные примеры по 

  • t
  • passthrough
  • placeholder 
  • drupal_escape
  • safe_json
  • without
  • clean_class
  • clean_id

Перевод строк в шаблоне twig

Twig предусматривает использование строк для разных языков. Для того чтобы перевести строку нужно использовать тег {% trans %}. Заметьте как пишутся управляющие конструкции. Они используют знак процента %, чтобы отличаться от переменных.

{% trans %} Hello world {% endtrans %}

Также мы можем передавать переменные в строки для перевода:

{% trans %} Hello {{ name }} {% endtrans %}

Также мы можем видоизменять переменные через фильтры перед выводом в строках перевода

{% set name = name|capitalize %}
 
{% trans %}
  Hello {{ name }}!
{% endtrans %}

Также twig поддерживает правильный вывод окончаний для слов в множественном числе (1 рубль, 2 рубля, 5 рублей):

{% trans %}
  Hello star.
{% plural count %}
  Hello {{ count }} stars.
{% endtrans %}

Комментарии Twig

Для комментариев в Twig используйте конструкцию с диезами:

{# Comment here #}

Оператор if

Хоть мы и не имеем большинства возможностей PHP в twig, но у нас есть набор конструкций для работы с массивами и переменных. Например мы можем проверить существуют ли переменная, прежде чем вывести эту переменную.

{% if site_slogan %}
  <div class="site-slogan">{{ site_slogan }}</div>
{% endif %}

Циклы Twig 

Очень часто в шаблонах нужно перебрать массив и вывести его поэлементно. Для этого в Twig мы используем цикл for (аналог foreach в PHP):

{% for item in items %}
  {{ item.content }}
{% endfor %}

Также мы можем использовать цикл for, как обычный цикл for для PHP, но только в другом виде:

{% for i in range(0, 3) %}
  {{ i }},
{% endfor %}

 

Функция range() генерирует массив с элементами от 0 до 3, по которым идет перебор.

Внутри цикла вы можете обращаться к указателю на текущий элемент в массиве с помощью следующих переменных:

Variable    Description
items.index     Current item number starting at 1
items.index0    Current item number starting at 0
items.revindex    The number of the current element from the end, starting from 1
items.revindex0    The number of the current element from the end, starting at 0
items.first    TRUE if this is the first item
items.last    TRUE if this is the last item
items.length    Item array length
items.parent    Parent context

 

Также мы можем использовать конструкцию for else

<ul>
{% for user in users %}
  <li>{{ user.username|e }}</li>
{% else %}
  <li><em>no user foundem></li>
{% endfor %}
</ul>