【问题标题】:How to change Twig loader via Symfony2 settings如何通过 Symfony2 设置更改 Twig 加载程序
【发布时间】:2011-01-13 16:57:20
【问题描述】:

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

提前谢谢你的任何提示

【问题讨论】:

    标签: symfony twig


    【解决方案1】:

    注册你自己的 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 上检查运行:

    应用程序/控制台容器:debug 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注入。不同之处在于,在编译器传递中,您可以访问每个服务,而不仅仅是您自己的服务。如您所见,chain loader 已被定义为 twig 环境的新 loader。

    要完成这个任务,你必须告诉 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 加载器作为后备。

    【讨论】:

      【解决方案2】:

      在 GitHub 上查看 this page。特别是&lt;parameter key="twig.loader.class"&gt;Symfony\Bundle\TwigBundle\Loader\Loader&lt;/parameter&gt;

      你可以在你的 config.yml 中配置这个键

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-24
          • 2013-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-27
          • 1970-01-01
          相关资源
          最近更新 更多