注册您自己的 twig 加载器 + 告诉 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_Loader接口.
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 并且仍然使用它自己的默认值“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 注入之外什么也不做。不同之处在于,在编译器过程中,您可以访问每个服务,而不仅仅是您自己的服务。正如您所看到的,链加载器已被定义为 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 加载器作为后备。