7

我尝试加载一个从 symfony 的默认位置移动到自定义位置的简单base.html.twig模板文件。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 在全局空间中哪里可以找到模板文件?

提前致谢。

4

5 回答 5

12

有一个本机功能可以以一种很好的方式完全满足您的需求。本质上,您可以像这样在 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_pa ​​ths.html

于 2014-05-07T05:48:26.803 回答
6

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

提供了一个可以简单使用的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

最后但并非最不重要的一点是更改扩展树枝文件并::从默认模板的命名空间中删除: {% extends 'base.html.twig' %}.

于 2012-10-19T09:47:08.027 回答
5

我设法找到了另一种实施起来更快的解决方案。我确实首先尝试了这个问题的公认答案,但仍然遇到路径问题。

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

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

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

于 2013-08-19T14:34:45.430 回答
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');
   }
...
}
于 2012-12-30T10:25:41.467 回答
1

假设您希望在全局范围内完成此操作,则此类内容应在编译器 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'));
    }
}
于 2014-07-14T14:30:57.933 回答