Loading Twig templates from an additional directory
The standard Twig loader in a Symfony app loads templates from the app/ directory and from Bundle resources. To load them from an additional location, it is possible to add a custom loader.
Since Twig uses a single loader, Twig_Loader_Chain
is used to wrap the original loader and the new custom loader. The original loader is registered in the container as twig.loader
, the custom loader will be a configured instance of Twig_Loader_Filesystem
. The following configuration puts it altogether.
symfony_blog.twig.loader.custom:
class: Twig_Loader_Filesystem
arguments: [ %custom_template_path% ]
tags:
- { name: templating.loader }
symfony_blog.twig.loader.chain:
class: Twig_Loader_Chain
calls:
- [ addLoader, [@symfony_blog.twig.loader.custom] ]
- [ addLoader, [@twig.loader] ]
Next, we need to set our chain loader in Twig. This is not possible in YAML, a compiler pass is needed.
<?php
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class CustomLoaderPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('twig');
$definition->addMethodCall('setLoader', [new Reference('symfony_blog.twig.loader.custom')]);
}
}
To register the compiler pass, we simply add it in the Bundle class.
<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ExampleBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CustomLoaderPass());
}
}