Symfony2:Twig:自定义位置中的默认模板文件

时间:2012-10-18 10:16:09

标签: php symfony twig

我尝试加载一个简单的base.html.twig模板文件,该文件已从symfony的默认位置app/Resources/views/移至自定义位置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在全球空间中找到模板文件的位置?

提前致谢。

5 个答案:

答案 0 :(得分:11)

有一个本机功能可以很好地完成您想要的功能。您可以在app / config.yml中的twig配置中添加一个twig命名空间,如下所示:

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

答案 1 :(得分:7)

由于亚当的暗示,我能够自己回答这个问题。如果有人有兴趣,我想提供我的答案。

AcmeDemoBundle提供了您可以使用的枝条扩展(类Acme\DemoBundle\Twig\Extension\DemoExtension)。将构造函数更改为

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

现在告诉symfony注册twig扩展名。修改您的config.yml文件(例如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' %}

答案 2 :(得分:5)

我设法找到了另一个解决方案,它实现起来要快得多。我确实首先尝试了这个问题的接受答案,但仍然有这样的路径问题。

在我的渲染调用模板之前,我添加了twig.loader容器的路径,如下所示:

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

现在,twig模板将从根文件夹中名为“theme”的目录中呈现。我从Fabien Pontencier本人(Symfony和Twig的创建者)那里找到了解决这个问题的答案:https://github.com/symfony/symfony/issues/1912

答案 3 :(得分:2)

从一个动作中你可以从(服务) - 容器获得'twig.loader'服务:

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

然后您可以在模板中使用此路径。

@besta用枝条扩展做了它,将twig加载器注入构造函数。但在twig扩展中,您可以使用环境:

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

答案 4 :(得分:1)

假设您希望全局完成此操作,则此类内容应在compiler 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'));
    }
}