added the real template name when an error occurs in a Twig template

This commit is contained in:
Fabien Potencier 2011-11-07 20:03:35 +01:00
parent b957515a17
commit 47b888a957
8 changed files with 33 additions and 6 deletions

View File

@ -43,6 +43,10 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
* moved the data collector to the bridge
* replaced MessageLogger class with the one from Swiftmailer 4.1.3
### TwigBundle
* added the real template name when an error occurs in a Twig template
### WebProfilerBundle
* added a routing panel

View File

@ -15,6 +15,7 @@ use Symfony\Bundle\TwigBundle\TwigEngine;
use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\HttpKernel\Debug\Stopwatch;
use Symfony\Component\Config\FileLocatorInterface;
/**
* Times the time spent to render a template.
@ -33,9 +34,9 @@ class TimedTwigEngine extends TwigEngine
* @param GlobalVariables|null $globals A GlobalVariables instance or null
* @param Stopwatch $stopwatch A Stopwatch instance
*/
public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, Stopwatch $stopwatch, GlobalVariables $globals = null)
public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, FileLocatorInterface $locator, Stopwatch $stopwatch, GlobalVariables $globals = null)
{
parent::__construct($environment, $parser, $globals);
parent::__construct($environment, $parser, $locator, $globals);
$this->stopwatch = $stopwatch;
}

View File

@ -12,6 +12,7 @@
<service id="debug.templating.engine.twig" class="%debug.templating.engine.twig.class%" public="false">
<argument type="service" id="twig" />
<argument type="service" id="templating.name_parser" />
<argument type="service" id="templating.locator" />
<argument type="service" id="debug.stopwatch" />
<argument type="service" id="templating.globals" />
</service>

View File

@ -40,6 +40,7 @@
<service id="templating.engine.twig" class="%templating.engine.twig.class%" public="false">
<argument type="service" id="twig" />
<argument type="service" id="templating.name_parser" />
<argument type="service" id="templating.locator" />
<argument type="service" id="templating.globals" />
</service>

View File

@ -25,7 +25,8 @@ class TwigEngineTest extends TestCase
{
$environment = $this->getTwigEnvironment();
$container = $this->getContainer();
$engine = new TwigEngine($environment, new TemplateNameParser(), $app = new GlobalVariables($container));
$locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface');
$engine = new TwigEngine($environment, new TemplateNameParser(), $locator, $app = new GlobalVariables($container));
$template = $this->getMock('\Twig_TemplateInterface');
@ -44,7 +45,8 @@ class TwigEngineTest extends TestCase
{
$environment = $this->getTwigEnvironment();
$container = new Container();
$engine = new TwigEngine($environment, new TemplateNameParser(), new GlobalVariables($container));
$locator = $this->getMock('Symfony\Component\Config\FileLocatorInterface');
$engine = new TwigEngine($environment, new TemplateNameParser(), $locator, new GlobalVariables($container));
$template = $this->getMock('\Twig_TemplateInterface');

View File

@ -13,8 +13,10 @@ namespace Symfony\Bundle\TwigBundle;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables;
use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Config\FileLocatorInterface;
/**
* This engine knows how to render Twig templates.
@ -25,6 +27,7 @@ class TwigEngine implements EngineInterface
{
protected $environment;
protected $parser;
protected $locator;
/**
* Constructor.
@ -33,10 +36,11 @@ class TwigEngine implements EngineInterface
* @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
* @param GlobalVariables|null $globals A GlobalVariables instance or null
*/
public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, GlobalVariables $globals = null)
public function __construct(\Twig_Environment $environment, TemplateNameParserInterface $parser, FileLocatorInterface $locator, GlobalVariables $globals = null)
{
$this->environment = $environment;
$this->parser = $parser;
$this->locator = $locator;
if (null !== $globals) {
$environment->addGlobal('app', $globals);
@ -56,7 +60,19 @@ class TwigEngine implements EngineInterface
*/
public function render($name, array $parameters = array())
{
return $this->load($name)->render($parameters);
try {
return $this->load($name)->render($parameters);
} catch (\Exception $e) {
if ($name instanceof TemplateReference) {
try {
// try to get the real file name of the template where the error occurred
$e->setTemplateFile(sprintf('%s', $this->locator->locate($this->parser->parse($e->getTemplateFile()))));
} catch (\Exception $ex) {
}
}
throw $e;
}
}
/**

View File

@ -76,6 +76,7 @@ class ExceptionControllerTest extends TestCase
$container->register('templating.engine.twig',$this->getMockClass('Symfony\\Bundle\\TwigBundle\\TwigEngine'))
->addArgument($this->getMock('Twig_Environment'))
->addArgument($this->getMock('Symfony\\Component\\Templating\\TemplateNameParserInterface'))
->addArgument(new Definition($this->getMockClass('Symfony\Component\Config\FileLocatorInterface')))
->addArgument($this->getMock('Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables', array(), array($this->getMock('Symfony\\Component\\DependencyInjection\\Container'))));
$container->setAlias('templating', 'templating.engine.twig');
$container->setParameter('kernel.bundles', array());

View File

@ -60,6 +60,7 @@ class WebProfilerExtensionTest extends TestCase
$this->container->register('templating.engine.twig', $this->getMockClass('Symfony\\Bundle\\TwigBundle\\TwigEngine'))
->addArgument(new Definition($this->getMockClass('Twig_Environment')))
->addArgument(new Definition($this->getMockClass('Symfony\\Component\\Templating\\TemplateNameParserInterface')))
->addArgument(new Definition($this->getMockClass('Symfony\Component\Config\FileLocatorInterface')))
->addArgument(new Definition($this->getMockClass('Symfony\\Bundle\\FrameworkBundle\\Templating\\GlobalVariables'), array(new Definition($this->getMockClass('Symfony\\Component\\DependencyInjection\\Container')))));
$this->container->setParameter('kernel.bundles', array());
$this->container->setParameter('kernel.cache_dir', __DIR__);