Я переключил свой предпочтительный метод на использование класса Twig_Loader_Chain. Этот метод позволяет назначить несколько загрузчиков в один экземпляр Twig_Environment, так что вы сможете прозрачно обрабатывать шаблоны из файлов или из строк. В нижней части статьи вы увидите описание этого метода.
Для того, чтобы создать twig шаблон требуется экземпляр класса Twig_Environment. Этот класс содержит метод render, который возвращает обработанный результат из twig шаблона (обычно из файла). Twig Environment использует загрузчик классов, который реализует интерфейс Twig_LoaderInterface, этот класс загружает данные из хранилища (файл, база данных) для последующего их анализа шаблонизатором. По умолчанию Symfony2 использует класс Twig_Loader_Filesystem, который загружает данные шаблонов из файлов, для того чтобы создать шаблон из строки нам нужен экземпляр Twig_Environment, который для получения данных, использует класс Twig_Loader_String. Есть несколько способов, как вы можете это сделать, самый простой способ — это создать экземпляр Twig_Environment и и в качестве загрузчика передать ему экземпляр класса Twig_Loader_String (этот код можно поместить внутри вашего контроллера):
<?php
$twig = new \Twig_Environment(new \Twig_Loader_String());
$rendered = $twig->render(
"Test string template: {{ result }}",
array("result" => "Success!")
);
Это прекрасно работает как быстрое решение, но проблема здесь заключается в том, что в шаблоне вы не будете иметь доступ к Symfony сервисам или пользовательским сервисам, это потому, что мы создали свежий экземпляр Twig_Environment без каких-либо дополнительных настроек, которые предоставляет Symfony. Лучше взять копию существующего сервиса Twig_Environment, используемого самим Symfony и изменить его для использования Twig_Loader_String
(вы можете использовать это в вашем контроллере):
<?php
$twig = clone $this->get('twig');
$twig->setLoader(new \Twig_Loader_String());
$rendered = $twig->render(
"Test string template: {{ result|humanize }}",
array("result" => "mega_success")
);
Здесь я клонировал оригинальный сервис Symfony, чтобы убедиться, что Symfony по-прежнему может обработать шаблон из файла. Другой метод заключается в том, чтобы создать свой собственный Twigсервис с помощью системы внедрения зависимостей Symfony. Здесь я добавил пользовательский Twig сервис в мой config.yml
проекта:
services:
mine.twig_string_loader:
class: "Twig_Loader_String"
mine.twig_string:
class: "%twig.class%"
arguments: [@mine.twig_string_loader, %twig.options% ]
Затем можно использовать этот сервис в пределах вашего контроллера, вот так:
<?php
$rendered = $this->get('mine.twig_string')->render(
"Test string template: {{ result }}",
array("result" => "Success!")
);
К сожалению, этот метод имеет те же ловушки как и в первом методе, он не будет включать любые Symfony Twig расширения или собственные расширения. Конечно эти расширения можно добавить в этот пользовательский Twig сервис, но гораздо легче просто клонировать существующий Twig сервис и изменить, при необходимости. Как упоминалось выше использование Twig Chain Loader , является предпочтительным методом, используйте его, чтобы назначить несколько загрузчиков Symfony в основной Twig экземпляр. Для использования этого метода необходимо использовать Symfony2.2 или выше. Добавление дополнительного загрузчика к экземпляру Symfony Twig может быть достигнуто путем создания нового Twig_Loader_String загрузчика, следующим образом:
twig.stringloader:
class: Twig_Loader_String
tags:
- { name: twig.loader }
Эти настройки должны быть добавлены в файл config.yml
или конфигурационный файл вашего бандла. Важной частью здесь является тег twig.loader
— это говорит Symfony, что нужно назначить класс Twig_Loader_String, как дополнительный загрузчик в основной Twig экземпляр. Красота этого метода заключается в том, что Symfony будет отображать шаблоны из файлов и строковые шаблоны прозрачно без каких-либо дополнительных усилий. Вы можете просто вызвать метод render и передать в него строку или ссылку на файл шаблона, и Twig сам определит, какой загрузчик использовать для вашего шаблона. Ниже приведен пример этого в действии:
<?php
class DefaultController extends Controller
{
public function indexAction()
{
$renderedString = $this->get('twig')->render('{{ name }}', array('name' => 'test'));
$renderedTemplate = $this->get('twig')->render('MyBundle:Default:index.html.twig');
}
}
Оба вызова будут успешно обрабатывать шаблоны. Twig сервис определит, какой загрузчик нужно использовать на основе предоставленных данных.