Symfony2: Twig: Default template file in custom location

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

I try to load a simple base.html.twig template file that was moved from symfony's default location app/Resources/views/ to the custom location theme/.

The template file contains:

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

Extending the above template file by the controller Acme\Core\CoreBundle\Controller by using the controller-specific template

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

leads to an error saying Unable to find template "::base.html.twig" in "AcmeCoreCoreBundle:Default:index.html.twig"..

How is it possible to tell symfony where to find the template files in global space?

Thanks in advance.

回答1:

There's a native feature to do exactly what you want in a nice way. Escentially you can add a twig namespace to the twig configuration in app/config.yml like this:

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

This creates an alias to the folder vendor/acme/foo-bar/templates and then you can use it to render your templates either from the controllers:

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

or from other twig templates

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

Source: official cookbook http://symfony.com/doc/current/cookbook/templating/namespaced_paths.html



回答2:

Due to Adam's hint I am able to answer the question on my own. So I want to provide my answer if anybody is interested in.

The AcmeDemoBundle provides a twig extension (class Acme\DemoBundle\Twig\Extension\DemoExtension) that you simply can use. Change the constructor to

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

Now tell symfony to register the twig extension. Edit your config.yml file (e.g. app/config/config.yml) and append

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

Last but not least change your extending twig file and remove the :: from your default template's namespace: {% extends 'base.html.twig' %}.



回答3:

I managed to find another solution to this which is much quicker to implement. I did try the accepted answer on this question first but was still having so path issues.

Just before my render call the template I added the path to the twig.loader container like this:

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

Now twig templates will be rendered from a directory called 'theme' in the root folder. I found this solution from Fabien Pontencier himself (the creator of Symfony and Twig) on a reply to a twig bug here: https://github.com/symfony/symfony/issues/1912



回答4:

From an action you can get the 'twig.loader'-service from the (service)-container:

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

And then you can use this path in your template.

@besta did it with a twig extension, injecting the twig loader into the constructor. But in twig extension you can use the environment:

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


回答5:

Assuming you want this done globally, this sort of stuff is meant to be done in a compiler pass.

It would be much cleaner and efficient like this:

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!