如何通过Symfony2设置更改Twig加载程序

时间:2011-01-13 16:57:20

标签: symfony twig

我编写了自定义的Twig加载程序,可以从数据库中获取模板,它可以在Twig“独立”库中运行。 现在我想在Symfony2中使用它,但无法通过Symfony2设置找到更改Twig加载器的位置。

提前获取有关该

的任何提示

3 个答案:

答案 0 :(得分:9)

注册您自己的树枝装载机+告诉Twig_Loader_Chain首先尝试装载您的装载机。您可以根据需要为Twig_Loader_Chain创建和添加任意数量的加载器。

services:
    Acme.corebundle.twig.loader.filesystem:
        class: Acme\CoreBundle\Twig\Loader\Filesystem
        tags:
            - { name: templating.loader }

    Acme.corebundle.twig_chain_loader:
        class: Twig_Loader_Chain
        calls:
            - [ addLoader, [@Acme.corebundle.twig.loader.filesystem] ]
            - [ addLoader, [@twig.loader] ]

现在你应该创建你的装载机。 Twig加载器必须实现Twig_LoaderInterface

的Acme / CoreBundle /枝条/装载机/ Filesystem.php

伪代码:     

namespace Acme\CoreBundle\Twig\Loader;

use Twig_LoaderInterface;


class Filesystem implements Twig_LoaderInterface {

    /**
     * {@inheritdoc}
     */
    public function getSource($name)
    {
        //code...
    }

    /**
     * {@inheritdoc}
     */
    protected function findTemplate($name)
    {
        //code...
    }

    /**
     * {@inheritdoc}
     */
    public function isFresh($template, $time)
    {
        //code...
    }

    //...
}

现在我们已经定义了我们的服务并创建了一个新的加载器。 问题是Twig不知道我们的新Twig_Loader并且仍然使用它自己的-default-“twig.loader”。

要检查CLI上的运行:

app / console容器:debug twig.loader

为了修改自己的bundle之外的服务,你必须使用CompilerPasses。 创建我们自己的,将您的加载器服务分配给树枝环境:

的Acme / CoreBundle / DependencyInjection /编译器/ TwigFileLoaderPass.php

<?php

namespace Acme\CoreBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class TwigFileLoaderPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('twig');
        $definition->addMethodCall('setLoader', array(new Reference('Acme.corebundle.twig_chain_loader')));
    }
}

有“addMethodCall”调用,它只是在服务定义中定义setter注入。不同之处在于,在编译器传递中,您可以访问每个服务,而不仅仅是您自己的服务。如您所见,链式加载器已被定义为树枝环境的新加载器。

要完成此任务,您必须告诉Symfony它应该使用此编译器传递。可以在bundle类中添加编译器传递:

的Acme / CoreBundle / AcmeCoreBundle.php

<?php

namespace Acme\CoreBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;

use Acme\CoreBundle\DependencyInjection\Compiler\TwigFileLoaderPass;

class AcmeCoreBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new TwigFileLoaderPass());
    }
}

如果相应的文件不存在,则新的Twig_Loader_Filesystem会抛出错误,并且链式加载器继续使用默认的twig加载器作为回退。

答案 1 :(得分:3)

在GitHub上查看this page。特别<parameter key="twig.loader.class">Symfony\Bundle\TwigBundle\Loader\Loader</parameter>

您可以在config.yml

中配置此密钥

答案 2 :(得分:1)

要覆盖config.yml中的密钥,您需要在服务而不是twig下执行此操作,因为此时配置解析器不支持(2.0.9)

twig:
    cache:...
    debug:...
    ...

services:
        twig.loader:
            class: Acme\CoreBundle\Twig\Loader\FilesystemLoader