a Sensio Labs Product

Гибкий, быстрый и безопасный
шаблонизатор для PHP

Жизнь на краю: динамическое и условное наследование

Сегодня мы поговорим о наследовании шаблонов. С тех пор как был создан Twig, очень многие интересуются – как делать динамические и/или условные шаблоны.

До версии Twig 0.9.6 включительно, тэг extends мог использоваться используется только со статическим именем шаблона.

{% extends "layout.twig" %}

...

Но что если вы хотите изменять имя макета? Скажем в зависимости от того является запрос AJAX или нет? Это стало возможным в Twig 0.9.7.

Во-первых, можно хранить название макета в переменной и передавать ее в шаблон.

{% extends layout %}

Здесь layout – это строковая переменная, которая содержит название шаблона и ее значение задается в контроллере, в зависимости от заголовка запроса.

Но есть и другой способ. Если вы хотите принять решение о подключаемом макете непосредственно в самом шаблоне, можно сделать следующее:

{% extends is_ajax ? 'layout_ajax.twig' : 'layout.twig' %}

Фактически, именем шаблона может быть любое валидное выражение (как это уже сделано с тэгом include); итак, теперь разрешено такое использование тэга extends:

{% extends 'layout' ~ extension %}

Вместо того, чтобы передавать шаблон как строку, вы можете передать непосредственно сам шаблон Twig_Template:

// {% extends layout %}

$layout = $twig->loadTemplate('some_layout_template.twig');

$twig->display('template.twig', array('layout' => $layout));

Заметьте, что аналогичная возможность добавлена и в тэг include:

// {% include template %}

// {% include template %}

$template = $twig->loadTemplate('some_template.twig');

$twig->display('template.twig', array('template' => $template));

А что под капотом?

Поддержка динамического наследования шаблонов была не простой задачей, так как Twig основывался на наследование классов в PHP. И, конечно, невозможно динамически менять родительский класс в PHP:

$bar = 'SomeBaseClass';

class Foo extends $bar
{
    // ...
}

Итак, Twig не использует больше PHP наследование, а просто имитирует его. Тесты производительности показывают, что скорость работы понижается незначительно. Уверен, что этот дает много возможностей и повышает гибкость приложения.

Если вам интересны подробности в коде – взгляните на лог изменений.

Добавить комментарий