Spec-Zone.ru › Twig 2

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)

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

  • base_template_class string (по умолчанию \Twig\Template)

    Базовый класс шаблона, используемый для сгенерированных шаблонов.

  • 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 #}
    
  • Выражения, результат которых представляет собой литерал или переменную, помеченную как безопасная, никогда не экранируются автоматически:

    {{ 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 #}
    
  • Автоматическое экранирование не применяется, если последний фильтр в цепочке помечен как безопасный для текущего контекста (например, 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/2.x/api.html

Spec-Zone.ru

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