Added {% try %} ... {% catch %} Error: {{ e.message }} {% endcatch %} tag to allow basic exception handling inside Twig

This commit is contained in:
Matias Griese
2017-10-30 13:31:47 +02:00
parent 18c597b3d2
commit 586fcf42ab
5 changed files with 136 additions and 7 deletions

View File

@@ -7,6 +7,7 @@
* Added `Grav\Framework\Object` classes for creating collections of objects
* Added `Grav\Framework\Page` interfaces
* Added `|nicenumber` Twig filter
* Added `{% try %} ... {% catch %} Error: {{ e.message }} {% endcatch %}` tag to allow basic exception handling inside Twig
* Deprecated GravTrait
1. [](#improved)
* Make it possible to include debug bar also into non-HTML responses

View File

@@ -74,7 +74,7 @@ class Debugger
*/
public function enabled($state = null)
{
if (isset($state)) {
if ($state !== null) {
$this->enabled = $state;
}
@@ -92,7 +92,7 @@ class Debugger
// Only add assets if Page is HTML
$page = $this->grav['page'];
if ($page->templateFormat() != 'html') {
if ($page->templateFormat() !== 'html') {
return $this;
}
@@ -107,13 +107,13 @@ class Debugger
// Get the required CSS files
list($css_files, $js_files) = $this->renderer->getAssets(null, JavascriptRenderer::RELATIVE_URL);
foreach ($css_files as $css) {
foreach ((array)$css_files as $css) {
$assets->addCss($css);
}
$assets->addCss('/system/assets/debugger.css');
foreach ($js_files as $js) {
foreach ((array)$js_files as $js) {
$assets->addJs($js);
}
}
@@ -166,7 +166,7 @@ class Debugger
if ($this->enabled()) {
// Only add assets if Page is HTML
$page = $this->grav['page'];
if ($page->templateFormat() != 'html' || !$this->renderer) {
if (!$this->renderer || $page->templateFormat() !== 'html') {
return $this;
}
@@ -216,7 +216,7 @@ class Debugger
*/
public function startTimer($name, $description = null)
{
if ($name[0] == '_' || $this->enabled()) {
if ($name[0] === '_' || $this->enabled()) {
$this->debugbar['time']->startMeasure($name, $description);
$this->timers[] = $name;
}
@@ -233,7 +233,7 @@ class Debugger
*/
public function stopTimer($name)
{
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->enabled())) {
if (in_array($name, $this->timers, true) && ($name[0] === '_' || $this->enabled())) {
$this->debugbar['time']->stopMeasure($name);
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* @package Grav.Common.Twig
*
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Twig;
/**
* Handles try/catch in template file.
*
* <pre>
* {% try %}
* <li>{{ user.get('name') }}</li>
* {% catch %}
* {{ e.message }}
* {% endcatch %}
* </pre>
*/
class TokenParserTry extends \Twig_TokenParser
{
/**
* Parses a token and returns a node.
*
* @param \Twig_Token $token A Twig_Token instance
*
* @return \Twig_NodeInterface A Twig_NodeInterface instance
*/
public function parse(\Twig_Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
$try = $this->parser->subparse([$this, 'decideCatch']);
$stream->next();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
$catch = $this->parser->subparse([$this, 'decideEnd']);
$stream->next();
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
return new TwigNodeTry($try, $catch, $lineno, $this->getTag());
}
public function decideCatch(\Twig_Token $token)
{
return $token->test(array('catch'));
}
public function decideEnd(\Twig_Token $token)
{
return $token->test(array('endtry')) || $token->test(array('endcatch'));
}
/**
* Gets the tag name associated with this token parser.
*
* @return string The tag name
*/
public function getTag()
{
return 'try';
}
}

View File

@@ -148,6 +148,16 @@ class TwigExtension extends \Twig_Extension
];
}
/**
* @return array
*/
public function getTokenParsers()
{
return [
new TokenParserTry(),
];
}
/**
* Filters field name by changing dot notation into array notation.
*

View File

@@ -0,0 +1,52 @@
<?php
/**
* @package Grav.Common.Twig
*
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Twig;
class TwigNodeTry extends \Twig_Node
{
public function __construct(\Twig_NodeInterface $try, \Twig_NodeInterface $catch = null, $lineno, $tag = null)
{
parent::__construct(array('try' => $try, 'catch' => $catch), array(), $lineno, $tag);
}
/**
* Compiles the node to PHP.
*
* @param \Twig_Compiler $compiler A Twig_Compiler instance
* @throws \LogicException
*/
public function compile(\Twig_Compiler $compiler)
{
$compiler->addDebugInfo($this);
$compiler
->write('try {')
;
$compiler
->indent()
->subcompile($this->getNode('try'))
;
if ($this->hasNode('catch') && null !== $this->getNode('catch')) {
$compiler
->outdent()
->write('} catch (\Exception $e) {' . "\n")
->indent()
->write('if (isset($context[\'grav\'][\'debugger\'])) $context[\'grav\'][\'debugger\']->addException($e);' . "\n")
->write('$context[\'e\'] = $e;' . "\n")
->subcompile($this->getNode('catch'))
;
}
$compiler
->outdent()
->write("}\n");
}
}