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

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

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

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

расширение вышеуказанного файла шаблона контроллером AcmeCoreCoreBundleController С помощью шаблона, специфичного для контроллера

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

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

как можно сообщить symfony, где найти файлы шаблонов в global космос?

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

5 ответов


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

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

это создает псевдоним для папки 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


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

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

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

теперь скажите symfony зарегистрировать расширение twig. Редактировать (например,app/config/config.yml) и добавить

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

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


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

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

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

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


из действия вы можете получить "веточку".погрузчик ' - сервис от (сервис)-контейнер:

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

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

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

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

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

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

<?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'));
    }
}