我尝试加载一个简单的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在全球空间中找到模板文件的位置?
提前致谢。
答案 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'));
}
}