3

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

提前谢谢任何提示

4

3 回答 3

9

注册你自己的 twig loader + 告诉 Twig_Loader_Chain 首先尝试使用你的 loader 加载。您可以根据需要创建和添加尽可能多的加载器到您的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 loader 必须实现Twig_LoaderInterface

Acme/CoreBundle/Twig/Loader/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 上的运行情况:

应用程序/控制台容器:调试 twig.loader

为了修改您自己的捆绑之外的服务,您必须使用 CompilerPasses。创建我们自己的,将您的加载程序服务分配给 twig 环境:

Acme/CoreBundle/DependencyInjection/Compiler/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 注入。不同之处在于,在编译器通道中,您可以访问每个服务,而不仅仅是您自己的服务。如您所见,链加载器已被定义为 twig 环境的新加载器。

要完成这个任务,你必须告诉 Symfony 它应该使用这个编译器通道。编译器通行证可以添加到你的包类中:

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 加载器作为后备。

于 2014-06-25T14:31:10.390 回答
3

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

您可以在 config.yml 中配置此密钥

于 2011-01-13T19:17:15.153 回答
1

要覆盖 config.yml 中的密钥,您需要在 services not twig 下进行,因为目前配置解析器不支持它(2.0.9)

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

services:
        twig.loader:
            class: Acme\CoreBundle\Twig\Loader\FilesystemLoader
于 2012-01-09T00:32:02.867 回答