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]);
Доступны следующие параметры:
-
debugbooleanПри установке в
true, сгенерированные шаблоны имеют метод__toString(), который вы можете использовать для отображения сгенерированных узлов (по умолчаниюfalse). -
charsetstring (по умолчаниюutf-8)Кодировка символов, используемая шаблонами.
-
base_template_classstring (по умолчанию\Twig\Template)Базовый класс шаблона, используемый для сгенерированных шаблонов.
-
cachestring илиfalseАбсолютный путь для хранения скомпилированных шаблонов или
false, чтобы отключить кэширование (что по умолчанию). -
auto_reloadbooleanПри разработке с Twig полезно перекомпилировать шаблон всякий раз, когда изменяется исходный код. Если вы не укажете значение для опции
auto_reload, оно будет определено автоматически на основе значенияdebug. -
strict_variablesbooleanЕсли установлено в
false, Twig будет игнорировать некорректные переменные (переменные и/или атрибуты/методы, которых нет) и заменять их значениемnull. При установке вtrue, Twig вместо этого выбросит исключение (по умолчаниюfalse). -
autoescapestringУстанавливает стратегию автоматического экранирования по умолчанию (
name,html,js,css,url,html_attr, или обратный вызов PHP, который принимает имя файла шаблона и возвращает стратегию экранирования, которую следует использовать — обратный вызов не может быть именем функции, чтобы избежать конфликтов с встроенными стратегиями экранирования); установите вfalse, чтобы отключить автоматическое экранирование. Стратегия экранированияnameопределяет стратегию экранирования, используемую для шаблона, на основе расширения имени файла шаблона (эта стратегия не требует дополнительных затрат во время выполнения, поскольку автоматическое экранирование выполняется во время компиляции). -
optimizationsintegerФлаг, указывающий, какие оптимизации следует применять (по умолчанию
-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 - для загрузки шаблонов из строк в шаблоне.
-
TwigExtensionStringLoaderExtension: Определяет функцию
Расширения 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: Выбрасывается, когда вызывается недопустимый тег, фильтр или метод в шаблоне в режиме песочницы.
© 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