Symfony2: Twig: файл шаблона по умолчанию в настраиваемом месте

Я пытаюсь загрузить простой base.html.twig шаблона base.html.twig который был перемещен из app/Resources/views/ местоположения по умолчанию Symfony app/Resources/views/ в theme/ пользовательского местоположения theme/ .

Файл шаблона содержит:

  <!DOCTYPE html> <html> <head> ... </head> <body> {% block body %}{% endblock %} </body> </html> 

Расширение вышеуказанного файла шаблона контроллером Acme\Core\CoreBundle\Controller с использованием шаблона, специфичного для контроллера

  {% extends '::base.html.twig' %} {% block body %} Hello world! {% endblock %} 

приводит к ошибке: « Unable to find template "::base.html.twig" in "AcmeCoreCoreBundle:Default:index.html.twig". ,

Как можно сказать symfony, где найти файлы шаблонов в глобальном пространстве?

Заранее спасибо.

Есть естественная функция, которая делает именно то, что вы хотите красивым способом. Эссенциально вы можете добавить пространство имен твинов в конфигурацию ветки в app / config.yml следующим образом:

 twig: # ... paths: "%kernel.root_dir%/../vendor/acme/foo-bar/templates": foo_bar 

Это создает псевдоним для vendor/acme/foo-bar/templates папок vendor/acme/foo-bar/templates а затем вы можете использовать его для визуализации ваших шаблонов либо с контроллеров:

 return $this->render( '@foo_bar/template.html.twig', $data ); 

или из других шаблонов веток

 {% include '@foo_bar/template.html.twig' %} 

Источник: официальная поваренная книга http://symfony.com/doc/current/cookbook/templating/namespaced_paths.html

Из-за намека Адама я могу ответить на этот вопрос самостоятельно. Поэтому я хочу дать свой ответ, если кто-то заинтересован.

AcmeDemoBundle предоставляет расширение twig (класс Acme\DemoBundle\Twig\Extension\DemoExtension ), который вы просто можете использовать. Измените конструктор на

  public function __construct(FilesystemLoader $loader) { $this->loader = $loader; $this->loader->addPath('path/to/your/directory'); } 

Теперь скажите symfony, чтобы зарегистрировать расширение ветки. Измените файл config.yml (например, app/config/config.yml ) и добавьте

  services: demo.twig.extension class: Acme\DemoBundle\Twig\Extension\DemoExtension tags: - { name: twig.extension } arguments: - @Twig.loader 

И последнее, но не менее {% extends 'base.html.twig' %} изменить ваш расширяемый файл twig и удалить из пространства имен вашего шаблона :: {% extends 'base.html.twig' %} .

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

Незадолго до моего вызова рендеринга шаблона я добавил путь к контейнеру twig.loader следующим образом:

 $this->container->get('twig.loader')->addPath('../../../../theme/', $namespace = '__main__'); 

Теперь твиговые шаблоны будут отображаться из каталога с именем «тема» в корневой папке. Я нашел это решение у самого Фабьена Понтенсье (создателя Symfony и Twig) на ответе на твиг-ошибку здесь: https://github.com/symfony/symfony/issues/1912

Из действия вы можете получить услугу «twig.loader» из (службы) -контейнера:

 $this->get('twig.loader')->addPath('path/to/your/directory'); 

И тогда вы можете использовать этот путь в своем шаблоне.

@besta делал это с расширением ветки, впрыскивая загрузчик ветки в конструктор. Но в расширении twig вы можете использовать среду:

 class YourTwigExtension extends \Twig_Extension { ... public function initRuntime(\Twig_Environment $environment) { $this->environment = $environment; $this->environment->getLoader()->addPath(__DIR__ . '/Resources/views'); } ... } 

Предполагая, что вы хотите, чтобы это было сделано глобально, этот вид материала должен быть выполнен в проходе компилятора .

Было бы намного чище и эффективнее:

 <?php use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; class CustomCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { $loader = $container->getDefinition('twig.loader'); $loader->addMethodCall('addPath', array('/path/to/views')); } }