Skip to content

Commit

Permalink
made a big refactoring of the templating sub-framework
Browse files Browse the repository at this point in the history
 * better separation of concerns
 * made TwigBundle independant of the PHP Engine from FrameworkBundle (WIP)
 * removed one layer of abstraction in the Templating component (renderers)
 * made it easier to create a new Engine for any templating library
 * made engines lazy-loaded (PHP engine for instance is not started if you only use Twig)
 * reduces memory footprint (if you only use one engine)
 * reduces size of compiled classes.php cache file
  • Loading branch information
fabpot committed Jan 15, 2011
1 parent 6011073 commit 055b6e4
Show file tree
Hide file tree
Showing 46 changed files with 1,002 additions and 864 deletions.

This file was deleted.

@@ -0,0 +1,48 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;

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

class TemplatingPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if ($container->hasDefinition('templating')) {
return;
}

if ($container->hasDefinition('templating.engine.php')) {
$helpers = array();
foreach ($container->findTaggedServiceIds('templating.helper') as $id => $attributes) {
if (isset($attributes[0]['alias'])) {
$helpers[$attributes[0]['alias']] = $id;
}
}

$definition = $container->getDefinition('templating.engine.php');
$arguments = $definition->getArguments();
$definition->setArguments($arguments);

if (count($helpers) > 0) {
$definition->addMethodCall('setHelpers', array($helpers));
}
}

if ($container->hasDefinition('templating.engine.delegating')) {
$queue = new \SplPriorityQueue();
foreach ($container->findTaggedServiceIds('templating.engine') as $id => $attributes) {
$queue->insert($id, isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0);
}

$engines = array();
foreach ($queue as $engine) {
$engines[] = $engine;
}

$container->getDefinition('templating.engine.delegating')->addMethodCall('setEngineIds', array($engines));
}
}
}
Expand Up @@ -231,21 +231,8 @@ protected function registerTemplatingConfiguration(array $config, ContainerBuild

// compilation
$this->addCompiledClasses($container, array(
'Symfony\\Component\\Templating\\Loader\\LoaderInterface',
'Symfony\\Component\\Templating\\Loader\\Loader',
'Symfony\\Component\\Templating\\Loader\\FilesystemLoader',
'Symfony\\Component\\Templating\\Engine',
'Symfony\\Component\\Templating\\Renderer\\RendererInterface',
'Symfony\\Component\\Templating\\Renderer\\Renderer',
'Symfony\\Component\\Templating\\Renderer\\PhpRenderer',
'Symfony\\Component\\Templating\\Storage\\Storage',
'Symfony\\Component\\Templating\\Storage\\FileStorage',
'Symfony\\Bundle\\FrameworkBundle\\Templating\\Engine',
'Symfony\\Component\\Templating\\Helper\\Helper',
'Symfony\\Component\\Templating\\Helper\\SlotsHelper',
'Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\ActionsHelper',
'Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper',
'Symfony\\Bundle\\FrameworkBundle\\Templating\\Helper\\RouterHelper',
'Symfony\\Component\\Templating\\DelegatingEngine',
'Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface',
));
}

Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
Expand Up @@ -3,7 +3,7 @@
namespace Symfony\Bundle\FrameworkBundle;

use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddTemplatingRenderersPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddSecurityVotersPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConverterManagerPass;
Expand Down Expand Up @@ -67,7 +67,7 @@ public function registerExtensions(ContainerBuilder $container)
$container->addCompilerPass(new RoutingResolverPass());
$container->addCompilerPass(new ProfilerPass());
$container->addCompilerPass(new RegisterKernelListenersPass());
$container->addCompilerPass(new AddTemplatingRenderersPass());
$container->addCompilerPass(new TemplatingPass());
$container->addCompilerPass(new AddConstraintValidatorsPass());
}
}
21 changes: 12 additions & 9 deletions src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml
Expand Up @@ -5,7 +5,8 @@
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">

<parameters>
<parameter key="templating.engine.class">Symfony\Bundle\FrameworkBundle\Templating\Engine</parameter>
<parameter key="templating.engine.delegating.class">Symfony\Bundle\FrameworkBundle\Templating\DelegatingEngine</parameter>
<parameter key="templating.engine.php.class">Symfony\Bundle\FrameworkBundle\Templating\PhpEngine</parameter>
<parameter key="templating.loader.filesystem.class">Symfony\Component\Templating\Loader\FilesystemLoader</parameter>
<parameter key="templating.loader.cache.class">Symfony\Component\Templating\Loader\CacheLoader</parameter>
<parameter key="templating.loader.chain.class">Symfony\Component\Templating\Loader\ChainLoader</parameter>
Expand All @@ -21,19 +22,25 @@
<parameter key="templating.helper.form.class">Symfony\Bundle\FrameworkBundle\Templating\Helper\FormHelper</parameter>
<parameter key="templating.assets.version">null</parameter>
<parameter key="templating.assets.base_urls" type="collection"></parameter>
<parameter key="templating.name_converter.class">Symfony\Bundle\FrameworkBundle\Templating\TemplateNameConverter</parameter>
<parameter key="templating.name_parser.class">Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser</parameter>
<parameter key="templating.renderer.php.class">Symfony\Component\Templating\Renderer\PhpRenderer</parameter>
<parameter key="debug.file_link_format">null</parameter>
</parameters>

<services>
<service id="templating.engine" class="%templating.engine.class%" public="false">
<service id="templating.engine.delegating" class="%templating.engine.delegating.class%" public="false">
<argument type="service" id="service_container" />
</service>

<service id="templating.engine.php" class="%templating.engine.php.class%">
<tag name="templating.engine" priority="128" />
<argument type="service" id="service_container" />
<argument type="service" id="templating.loader" />
<call method="setCharset"><argument>%kernel.charset%</argument></call>
</service>

<service id="templating.loader.filesystem" class="%templating.loader.filesystem.class%" public="false">
<argument type="service" id="templating.name_parser" />
<argument>%templating.loader.filesystem.path%</argument>
<call method="setDebugger"><argument type="service" id="templating.debugger" on-invalid="ignore" /></call>
</service>
Expand Down Expand Up @@ -100,16 +107,12 @@
<argument type="service" id="templating" />
</service>

<service id="templating.name_converter" class="%templating.name_converter.class%">
<service id="templating.name_parser" class="%templating.name_parser.class%">
<argument type="service" id="service_container" />
</service>

<service id="templating.renderer.php" class="%templating.renderer.php.class%">
<tag name="templating.renderer" alias="php" />
</service>

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

<service id="templating" alias="templating.engine" />
<service id="templating" alias="templating.engine.delegating" />
</services>
</container>
99 changes: 99 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Templating/DelegatingEngine.php
@@ -0,0 +1,99 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\Templating;

use Symfony\Component\Templating\DelegatingEngine as BaseDelegatingEngine;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\Response;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* DelegatingEngine selects an engine for a given template.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class DelegatingEngine extends BaseDelegatingEngine implements EngineInterface
{
protected $container;

/**
* Constructor.
*
* @param ContainerInterface $container The DI container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->engines = array();
}

public function setEngineIds($ids)
{
$this->engines = $ids;
}

/**
* {@inheritdoc}
*/
public function supports($name)
{
foreach ($this->engines as $i => $engine) {
if (is_string($engine)) {
$engine = $this->engines[$i] = $this->container->get($engine);
}

if ($engine->supports($name)) {
return true;
}
}

return false;
}

/**
* {@inheritdoc}
*/
protected function getEngine($name)
{
foreach ($this->engines as $i => $engine) {
if (is_string($engine)) {
$engine = $this->engines[$i] = $this->container->get($engine);
}

if ($engine->supports($name)) {
return $engine;
}
}

throw new \RuntimeException(sprintf('No engine is able to work with the "%s" template.', $name));
}

/**
* Renders a view and returns a Response.
*
* @param string $view The view name
* @param array $parameters An array of parameters to pass to the view
* @param Response $response A Response instance
*
* @return Response A Response instance
*/
public function renderResponse($view, array $parameters = array(), Response $response = null)
{
if (null === $response) {
$response = $this->container->get('response');
}

$response->setContent($this->render($view, $parameters));

return $response;
}
}
34 changes: 34 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Templating/EngineInterface.php
@@ -0,0 +1,34 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\Templating;

use Symfony\Component\Templating\EngineInterface as BaseEngineInterface;
use Symfony\Component\HttpFoundation\Response;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* EngineInterface is the interface each engine must implement.
*
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface EngineInterface extends BaseEngineInterface
{
/**
* Renders a view and returns a Response.
*
* @param string $view The view name
* @param array $parameters An array of parameters to pass to the view
* @param Response $response A Response instance
*
* @return Response A Response instance
*/
function renderResponse($view, array $parameters = array(), Response $response = null);
}

0 comments on commit 055b6e4

Please sign in to comment.