Spec-Zone.ru › Twig 3

Twig для разработчиков

В этом разделе описывается API Twig, а не сам язык шаблонов. Он будет наиболее полезен тем, кто реализует интерфейс шаблонов в приложении, а не тем, кто создаёт Twig-шаблоны.

Основы

Twig использует центральный объект, называемый средой (класса \Twig\Environment). Экземпляры этого класса используются для хранения конфигурации и расширений, а также для загрузки шаблонов.

Большинство приложений создают один объект \Twig\Environment при инициализации приложения и используют его для загрузки шаблонов. В некоторых случаях может быть полезно иметь несколько сред, работающих бок о бок с разными конфигурациями.

Типичный способ конфигурации Twig для загрузки шаблонов для приложения выглядит примерно так:

require_once '/path/to/vendor/autoload.php';

$loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
$twig = new \Twig\Environment($loader, [
    'cache' => '/path/to/compilation_cache',
]);

Это создаёт среду шаблонов с настройками по умолчанию и загрузчиком, который ищет шаблоны в каталоге /path/to/templates/. Доступны различные загрузчики, и вы также можете написать свой собственный, если хотите загружать шаблоны из базы данных или других ресурсов.

Примечание

Обратите внимание, что второй аргумент среды — массив опций. Опция cache — это каталог кэша компиляции, где Twig кэширует скомпилированные шаблоны, чтобы избежать фазы разбора для последующих запросов. Это сильно отличается от кэша, который вы можете добавить для обработанных шаблонов. Для такой потребности вы можете использовать любую доступную PHP-библиотеку кэширования.

Отображение шаблонов

Чтобы загрузить шаблон из среды Twig, вызовите метод load(), который возвращает экземпляр \Twig\TemplateWrapper.

$template = $twig->load('index.html');

Чтобы отобразить шаблон с некоторыми переменными, вызовите метод render().

echo $template->render(['the' => 'variables', 'go' => 'here']);

Примечание

Метод display() — это сокращение для вывода отрендеренного шаблона.

Вы также можете загрузить и отобразить шаблон одним шагом:

echo $twig->render('index.html', ['the' => 'variables', 'go' => 'here']);

Если шаблон определяет блоки, они могут быть отображены по отдельности с помощью вызова renderBlock().

echo $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);

Параметры среды

При создании нового экземпляра \Twig\Environment, вы можете передать массив опций в качестве второго аргумента конструктора:

$twig = new \Twig\Environment($loader, ['debug' => true]);

Доступны следующие опции:

  • debug boolean

    Если установлено в true, сгенерированные шаблоны имеют метод __toString(), который вы можете использовать для отображения сгенерированных узлов (по умолчанию false).

  • charset string (по умолчанию utf-8)

    Кодировка символов, используемая шаблонами.

  • cache string или false

    Абсолютный путь для хранения скомпилированных шаблонов или false, чтобы отключить кэширование (по умолчанию).

  • auto_reload boolean

    При разработке с Twig полезно перекомпилировать шаблон всякий раз, когда изменяется исходный код. Если вы не предоставите значение для опции auto_reload, оно будет определено автоматически на основе значения debug.

  • strict_variables boolean

    Если установлено в false, Twig будет игнорировать недействительные переменные (переменные и/или атрибуты/методы, которых не существует) и заменять их значением null. Если установлено в true, Twig вместо этого выбросит исключение (по умолчанию false).

  • autoescape string

    Устанавливает стратегию автоматического экранирования по умолчанию (name, html, js, css, url, html_attr, или PHP-обработчик, принимающий имя файла шаблона и возвращающий стратегию экранирования для использования — обработчик не может быть именем функции, чтобы избежать конфликта со встроенными стратегиями экранирования); установите значение false, чтобы отключить автоматическое экранирование. Стратегия экранирования name определяет стратегию экранирования для шаблона на основе расширения имени файла шаблона (эта стратегия не влечёт никаких накладных расходов во время выполнения, так как автоматическое экранирование выполняется на стадии компиляции).

  • optimizations integer

    Флаг, указывающий, какие оптимизации применять (по умолчанию -1, все оптимизации включены; установите значение 0, чтобы отключить).

Загрузчики

Загрузчики отвечают за загрузку шаблонов из таких ресурсов, как файловая система.

Кэш компиляции

Все загрузчики шаблонов могут кэшировать скомпилированные шаблоны в файловой системе для последующего использования. Это значительно ускоряет Twig, так как шаблоны компилируются только один раз.

Встроенные загрузчики

Вот список встроенных загрузчиков:

\Twig\Loader\FilesystemLoader

\Twig\Loader\FilesystemLoader загружает шаблоны из файловой системы. Этот загрузчик может находить шаблоны в папках на файловой системе и является предпочтительным способом их загрузки:

$loader = new \Twig\Loader\FilesystemLoader($templateDir);

Он также может искать шаблоны в массиве каталогов:

$loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);

С такой конфигурацией Twig сначала будет искать шаблоны в $templateDir1, а если они не найдутся, то вернётся к поиску в $templateDir2.

Вы можете добавлять или вставлять пути с помощью методов addPath() и prependPath().

$loader->addPath($templateDir3);
$loader->prependPath($templateDir4);

Загрузчик файловой системы также поддерживает шаблоны с именами пространства имён. Это позволяет группировать ваши шаблоны в различных пространствах имён, которые имеют свои собственные пути к шаблонам.

При использовании методов setPaths(), addPath(), и prependPath(), укажите пространство имён в качестве второго аргумента (если не указано, эти методы действуют на «главное» пространство имён):

$loader->addPath($templateDir, 'admin');

К шаблонам в пространствах имён можно получить доступ через специальное обозначение @namespace_name/template_path.

$twig->render('@admin/index.html', []);

\Twig\Loader\FilesystemLoader поддерживает абсолютные и относительные пути. Использование относительных путей предпочтительнее, так как это делает ключи кэша независимыми от корня проекта (например, это позволяет разогреть кэш с сервера сборки, где каталог может отличаться от того, который используется на серверах производства):

$loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..');

Примечание

Если не передавать корневой путь в качестве второго аргумента, Twig использует getcwd() для относительных путей.

\Twig\Loader\ArrayLoader

\Twig\Loader\ArrayLoader загружает шаблон из массива PHP. Ему передаётся массив строк, связанных с именами шаблонов:

$loader = new \Twig\Loader\ArrayLoader([
    'index.html' => 'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);

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

Этот загрузчик очень полезен для юнит-тестирования. Его также можно использовать для небольших проектов, где хранение всех шаблонов в одном PHP-файле может быть целесообразным.

Подсказка

При использовании загрузчика Array с механизмом кэширования, необходимо знать, что каждый раз, когда содержимое шаблона «изменяется» (ключом кэша является исходный код шаблона), генерируется новый ключ кэша. Если вы не хотите видеть, как ваш кэш разрастается, вам нужно позаботиться о самостоятельной очистке старых файлов кэша.

\Twig\Loader\ChainLoader

\Twig\Loader\ChainLoader делегирует загрузку шаблонов другим загрузчикам:

$loader1 = new \Twig\Loader\ArrayLoader([
    'base.html' => '{% block content %}{% endblock %}',
]);
$loader2 = new \Twig\Loader\ArrayLoader([
    'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
    'base.html'  => 'Will never be loaded',
]);

$loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);

$twig = new \Twig\Environment($loader);

При поиске шаблона Twig пробует каждый загрузчик по очереди и возвращает результат, как только шаблон найден. При отображении шаблона index.html из приведённого выше примера, Twig загрузит его с помощью $loader2, но шаблон base.html будет загружен из $loader1.

Примечание

Вы также можете добавить загрузчики с помощью метода addLoader().

Создайте собственный загрузчик

Все загрузчики реализуют интерфейс \Twig\Loader\LoaderInterface.

interface \Twig\Loader\LoaderInterface
{
    /**
     * Returns the source context for a given template logical name.
     *
     * @param string $name The template logical name
     *
     * @return \Twig\Source
     *
     * @throws \Twig\Error\LoaderError When $name is not found
     */
    public function getSourceContext($name);

    /**
     * Gets the cache key to use for the cache for a given template name.
     *
     * @param string $name The name of the template to load
     *
     * @return string The cache key
     *
     * @throws \Twig\Error\LoaderError When $name is not found
     */
    public function getCacheKey($name);

    /**
     * Returns true if the template is still fresh.
     *
     * @param string    $name The template name
     * @param timestamp $time The last modification time of the cached template
     *
     * @return bool    true if the template is fresh, false otherwise
     *
     * @throws \Twig\Error\LoaderError When $name is not found
     */
    public function isFresh($name, $time);

    /**
     * Check if we have the source code of a template, given its name.
     *
     * @param string $name The name of the template to check if we can load
     *
     * @return bool    If the template source code is handled by this loader or not
     */
    public function exists($name);
}

Метод isFresh() должен вернуть true, если текущий кэшированный шаблон по-прежнему актуален, учитывая время последней модификации, или false, в противном случае.

Метод getSourceContext() должен вернуть экземпляр \Twig\Source.

Использование расширений

Расширения Twig — это пакеты, которые добавляют новые возможности в Twig. Зарегистрируйте расширение через метод addExtension():

$twig->addExtension(new \Twig\Extension\SandboxExtension());

Twig поставляется со следующими расширениями:

  • TwigExtensionCoreExtension: Определяет все основные возможности Twig.
  • TwigExtensionDebugExtension: Определяет функцию dump для отладки переменных шаблонов.
  • TwigExtensionEscaperExtension: Добавляет автоматическое экранирование вывода и возможность экранирования/ра экранирования блоков кода.
  • TwigExtensionSandboxExtension: Добавляет режим песочницы к среде Twig по умолчанию, делая её безопасной для оценки недоверенного кода.
  • TwigExtensionProfilerExtension: Включает встроенный профайлер Twig.
  • TwigExtensionOptimizerExtension: Оптимизирует дерево узлов перед компиляцией.
  • TwigExtensionStringLoaderExtension: Определяет функцию template_from_string
    для загрузки шаблонов из строк в шаблоне.

Расширения Core, Escaper и Optimizer зарегистрированы по умолчанию.

Встроенные расширения

В этом разделе описаны возможности, добавленные встроенными расширениями.

Подсказка

Прочитайте главу о расширении Twig, чтобы узнать, как создавать свои собственные расширения.

Расширение ядра

Расширение core определяет все основные возможности Twig.

  • Теги;
  • Фильтры;
  • Функции;
  • Тесты.

Расширение Escaper

Расширение escaper добавляет автоматическую экранизацию вывода в Twig. Оно определяет тег autoescape и фильтр raw.

При создании расширения escaper вы можете включить или отключить глобальную стратегию экранизации вывода:

$escaper = new \Twig\Extension\EscaperExtension('html');
$twig->addExtension($escaper);

Если установлено значение html, все переменные в шаблонах экранируются (используя стратегию экранизации html), за исключением тех, которые используют фильтр raw.

{{ article.to_html|raw }}

Вы также можете изменить режим экранизации локально, используя тег autoescape.

{% autoescape 'html' %}
{{ var }}
{{ var|raw }}{# var won't be escaped #}
{{ var|escape }}{# var won't be double-escaped #}
{% endautoescape %}

Предупреждение

Тег autoescape не оказывает никакого влияния на включенные файлы.

Правила экранизации реализованы следующим образом:

  • Литералы (целые числа, булевы значения, массивы и т.д.), используемые в шаблоне непосредственно как переменные или аргументы фильтров, никогда не экранируются автоматически:

    {{ "Twig<br/>" }} {# won't be escaped #}
    
    {% set text = "Twig<br/>" %}
    {{ text }} {# will be escaped #}
    
  • Выражения, результат которых — литерал или переменная, помеченная как безопасная (safe), никогда не экранируются автоматически:

    {{ foo ? "Twig<br/>" : "<br/>Twig" }} {# won't be escaped #}
    
    {% set text = "Twig<br/>" %}
    {{ true ? text : "<br/>Twig" }} {# will be escaped #}
    {{ false ? text : "<br/>Twig" }} {# won't be escaped #}
    
    {% set text = "Twig<br/>" %}
    {{ foo ? text|raw : "<br/>Twig" }} {# won't be escaped #}
    
  • Объекты с методом __toString преобразуются в строки и экранируются. Вы можете пометить некоторые классы и/или интерфейсы как безопасные для некоторых стратегий с помощью EscaperExtension::addSafeClass().

    // mark object of class Foo as safe for the HTML strategy
    $escaper->addSafeClass('Foo', ['html']);
    
    // mark object of interface Foo as safe for the HTML strategy
    $escaper->addSafeClass('FooInterface', ['html']);
    
    // mark object of class Foo as safe for the HTML and JS strategies
    $escaper->addSafeClass('Foo', ['html', 'js']);
    
    // mark object of class Foo as safe for all strategies
    $escaper->addSafeClass('Foo', ['all']);
    
  • Экранирование применяется перед выводом, после применения любых других фильтров:

    {{ var|upper }}{# is equivalent to {{ var|upper|escape }} #}
    
  • Фильтр raw следует использовать только в конце цепочки фильтров:

    {{ var|raw|upper }}{# will be escaped #}
    
    {{ var|upper|raw }}{# won't be escaped #}
    
  • Автоматическая экранизация не применяется, если последний фильтр в цепочке помечен как безопасный (safe) для текущего контекста (например, html или js). escape и escape('html') помечены как безопасные для HTML, escape('js') — для JavaScript, raw — для всего.

    {% autoescape 'js' %}
    {{ var|escape('html') }}{# will be escaped for HTML and JavaScript #}
    {{ var }}{# will be escaped for JavaScript #}
    {{ var|escape('js') }}{# won't be double-escaped #}
    {% endautoescape %}
    

Примечание

Обратите внимание, что у автоматической экранизации есть некоторые ограничения, так как экранирование применяется к выражениям после вычисления. Например, при работе с конкатенацией {{ foo|raw ~ bar }} не даст ожидаемого результата, так как экранирование применяется к результату конкатенации, а не к отдельным переменным (поэтому фильтр raw здесь не повлияет).

Расширение Sandbox

Расширение sandbox может использоваться для оценки небезопасного кода. Доступ к небезопасным атрибутам и методам запрещен. Безопасность песочницы управляется объектом политики. По умолчанию Twig поставляется с одним классом политики: \Twig\Sandbox\SecurityPolicy. Этот класс позволяет вам создавать белый список некоторых тегов, фильтров, свойств и методов:

$tags = ['if'];
$filters = ['upper'];
$methods = [
    'Article' => ['getTitle', 'getBody'],
];
$properties = [
    'Article' => ['title', 'body'],
];
$functions = ['range'];
$policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);

С предыдущей конфигурацией политика безопасности позволит использовать только тег if, и фильтр upper. Кроме того, шаблоны смогут вызывать методы getTitle() и getBody() для объектов Article, и публичные свойства title и body. Всё остальное не будет разрешено и вызовет исключение \Twig\Sandbox\SecurityError.

Объект политики является первым аргументом конструктора песочницы:

$sandbox = new \Twig\Extension\SandboxExtension($policy);
$twig->addExtension($sandbox);

По умолчанию режим песочницы отключен и должен быть включён при включении небезопасного кода шаблона с помощью тега sandbox:

{% sandbox %}
{% include 'user.html' %}
{% endsandbox %}

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

$sandbox = new \Twig\Extension\SandboxExtension($policy, true);

Расширение Profiler

Расширение profiler включает профайлер для Twig-шаблонов; его следует использовать только на машинах разработки, так как оно добавляет некоторую нагрузку:

$profile = new \Twig\Profiler\Profile();
$twig->addExtension(new \Twig\Extension\ProfilerExtension($profile));

$dumper = new \Twig\Profiler\Dumper\TextDumper();
echo $dumper->dump($profile);

Профиль содержит информацию о времени и потреблении памяти для выполнения шаблонов, блоков и макросов.

Вы также можете выгрузить данные в формате, совместимом с Blackfire.io:

$dumper = new \Twig\Profiler\Dumper\BlackfireDumper();
file_put_contents('/path/to/profile.prof', $dumper->dump($profile));

Загрузите профиль, чтобы визуализировать его (сначала создайте бесплатный аккаунт):

blackfire --slot=7 upload /path/to/profile.prof

Расширение Optimizer

Расширение optimizer оптимизирует дерево узлов перед компиляцией:

$twig->addExtension(new \Twig\Extension\OptimizerExtension());

По умолчанию все оптимизации включены. Вы можете выбрать нужные вам оптимизации, передав их в конструктор:

$optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR);

$twig->addExtension($optimizer);

Twig поддерживает следующие оптимизации:

  • \Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL, включает все оптимизации (это значение по умолчанию).
  • \Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE, отключает все оптимизации. Это уменьшает время компиляции, но может увеличить время выполнения и потребление памяти.
  • \Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR, оптимизирует тег for путём удаления создания переменной loop, когда это возможно.
  • \Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER, удаляет фильтр raw, когда это возможно.
  • \Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_VAR_ACCESS, упрощает создание и доступ к переменным в скомпилированных шаблонах, когда это возможно.

Исключения

Twig может генерировать исключения:

  • \Twig\Error\Error: Базовое исключение для всех ошибок.
  • \Twig\Error\SyntaxError: Выбрасывается, чтобы сообщить пользователю о проблеме в синтаксисе шаблона.
  • \Twig\Error\RuntimeError: Выбрасывается при возникновении ошибки во время выполнения (например, когда фильтр не существует).
  • \Twig\Error\LoaderError: Выбрасывается, когда возникает ошибка при загрузке шаблона.
  • \Twig\Sandbox\SecurityError: Выбрасывается, когда в шаблоне песочницы вызывается недопустимый тег, фильтр или метод.
« Twig для разработчиков шаблонов | Расширение Twig »

© 2009–2018 by the Twig Team
Licensed under the three clause BSD license.
The Twig logo is © 2010–2020 Symfony
https://twig.symfony.com/doc/3.x/api.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API