Skip to content

Commit

Permalink
Added configuration pass that adds Twig Loaders
Browse files Browse the repository at this point in the history
- Added compiler class which picks up any services tagged "twig.loader"
- If there is one loader registered we set the alias to this loader
- If there is more than one we set the alias to a chain loader and all
  the loaders to it
- If there is no loaders we throw an Exception
  • Loading branch information
dantleech committed Dec 7, 2012
1 parent 9ab4a96 commit f48b22a
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Symfony/Bundle/TwigBundle/CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
2.2.0
-----

* added support for multiple loaders via the "twig.loader" tag.
* added automatic registration of namespaced paths for registered bundles
* added support for namespaced paths

Expand Down
@@ -0,0 +1,53 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;

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

/**
* If there are any tagged loaders replace
* default filesystem loader with chain loader
*
* Add tagged loaders to chain loader
*
* @author Daniel Leech <daniel@dantleech.com>
*/
class TwigLoaderPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('twig')) {
return;
}

// register additional template loaders
$loaderIds = $container->findTaggedServiceIds('twig.loader');

if (count($loaderIds) === 0) {
throw new LogicException('No twig loaders found. You need to tag at least one loader with "twig.loader"');
}

if (count($loaderIds) === 1) {
$container->setAlias('twig.loader', key($loaderIds));
} else {
$chainLoader = $container->getDefinition('twig.loader.chain');
foreach (array_keys($loaderIds) as $id) {
$chainLoader->addMethodCall('addLoader', array(new Reference($id)));
};
$container->setAlias('twig.loader', 'twig.loader.chain');
}
}
}

4 changes: 4 additions & 0 deletions src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
Expand Up @@ -7,6 +7,7 @@
<parameters>
<parameter key="twig.class">Twig_Environment</parameter>
<parameter key="twig.loader.filesystem.class">Symfony\Bundle\TwigBundle\Loader\FilesystemLoader</parameter>
<parameter key="twig.loader.chain.class">Twig_Loader_Chain</parameter>
<parameter key="templating.engine.twig.class">Symfony\Bundle\TwigBundle\TwigEngine</parameter>
<parameter key="twig.cache_warmer.class">Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer</parameter>
<parameter key="twig.extension.trans.class">Symfony\Bridge\Twig\Extension\TranslationExtension</parameter>
Expand Down Expand Up @@ -41,8 +42,11 @@
<service id="twig.loader.filesystem" class="%twig.loader.filesystem.class%" public="false">
<argument type="service" id="templating.locator" />
<argument type="service" id="templating.name_parser" />
<tag name="twig.loader"/>
</service>

<service id="twig.loader.chain" class="%twig.loader.chain.class%" public="false"/>

<service id="twig.loader" alias="twig.loader.filesystem" />

<service id="templating.engine.twig" class="%templating.engine.twig.class%" public="false">
Expand Down
@@ -0,0 +1,87 @@
<?php

namespace symfony\src\Symfony\Bundle\TwigBundle\Tests\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigLoaderPass;

class TwigLoaderPassTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->builder = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->chainLoader = new Definition('loader');
$this->pass = new TwigLoaderPass();
}

public function testMapperPassWithOneTaggedLoaders()
{
$serviceIds = array(
'test_loader_1' => array(
),
);

$this->builder->expects($this->once())
->method('hasDefinition')
->with('twig')
->will($this->returnValue(true));
$this->builder->expects($this->once())
->method('findTaggedServiceIds')
->with('twig.loader')
->will($this->returnValue($serviceIds));
$this->builder->expects($this->once())
->method('setAlias')
->with('twig.loader', 'test_loader_1');

$this->pass->process($this->builder);
}

public function testMapperPassWithTwoTaggedLoaders()
{
$serviceIds = array(
'test_loader_1' => array(
),
'test_loader_2' => array(
),
);

$this->builder->expects($this->once())
->method('hasDefinition')
->with('twig')
->will($this->returnValue(true));
$this->builder->expects($this->once())
->method('findTaggedServiceIds')
->with('twig.loader')
->will($this->returnValue($serviceIds));
$this->builder->expects($this->once())
->method('getDefinition')
->with('twig.loader.chain')
->will($this->returnValue($this->chainLoader));
$this->builder->expects($this->once())
->method('setAlias')
->with('twig.loader', 'twig.loader.chain');

$this->pass->process($this->builder);
$calls = $this->chainLoader->getMethodCalls();
$this->assertEquals(2, count($calls));
$this->assertEquals('addLoader', $calls[0][0]);
}

/**
* @expectedException Symfony\Component\DependencyInjection\Exception\LogicException
*/
public function testMapperPassWithZeroTaggedLoaders()
{
$this->builder->expects($this->once())
->method('hasDefinition')
->with('twig')
->will($this->returnValue(true));
$this->builder->expects($this->once())
->method('findTaggedServiceIds')
->with('twig.loader')
->will($this->returnValue(array()));

$this->pass->process($this->builder);
}
}
2 changes: 2 additions & 0 deletions src/Symfony/Bundle/TwigBundle/TwigBundle.php
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigLoaderPass;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ExceptionListenerPass;

/**
Expand All @@ -28,6 +29,7 @@ public function build(ContainerBuilder $container)
parent::build($container);

$container->addCompilerPass(new TwigEnvironmentPass());
$container->addCompilerPass(new TwigLoaderPass());
$container->addCompilerPass(new ExceptionListenerPass());
}
}

0 comments on commit f48b22a

Please sign in to comment.