From: Fabien Potencier Date: Thu, 4 Mar 2010 10:08:16 +0000 (+0100) Subject: added support for escaping strategy in the autoescape tag (closes #19) X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=6c7d5603ea3e5f12976f035068de4846527b696e;p=konrad%2Ftwig.git added support for escaping strategy in the autoescape tag (closes #19) --- diff --git a/CHANGELOG b/CHANGELOG index 2428d7b..7e05726 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 0.9.6-DEV + * added support for escaping strategy in the autoescape tag * fixed lexer when a template has a big chunk of text between/in a block * 0.9.5 (2010-01-20) diff --git a/doc/02-Twig-for-Template-Designers.markdown b/doc/02-Twig-for-Template-Designers.markdown index 5747696..4cf967e 100644 --- a/doc/02-Twig-for-Template-Designers.markdown +++ b/doc/02-Twig-for-Template-Designers.markdown @@ -361,6 +361,11 @@ template to be escaped or not by using the `autoescape` tag: Everything will be outputed as is in this block {% endautoescape %} + {% autoescape on js %} + Everything will be automatically escaped in this block + using the js escaping strategy + {% endautoescape %} + When automatic escaping is enabled everything is escaped by default except for values explicitly marked as safe. Those can be marked in the template by using the `|safe` filter. diff --git a/lib/Twig/Node/AutoEscape.php b/lib/Twig/Node/AutoEscape.php index 97c6e6d..98df7f7 100644 --- a/lib/Twig/Node/AutoEscape.php +++ b/lib/Twig/Node/AutoEscape.php @@ -12,6 +12,12 @@ /** * Represents an autoescape node. * + * The value is the escaping strategy (can be html, js, ...) + * + * The true value is equivalent to html. + * + * If autoescaping is disabled, then the value is false. + * * @package twig * @author Fabien Potencier * @version SVN: $Id$ diff --git a/lib/Twig/NodeVisitor/Escaper.php b/lib/Twig/NodeVisitor/Escaper.php index 098345a..1859dcb 100644 --- a/lib/Twig/NodeVisitor/Escaper.php +++ b/lib/Twig/NodeVisitor/Escaper.php @@ -19,9 +19,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface { $this->statusStack[] = $node->getValue(); } - elseif ($node instanceof Twig_Node_Print && true === $this->needEscaping($env)) + elseif ($node instanceof Twig_Node_Print) { - return $this->escapeNode($node, $env); + return $this->escapeNode($node, $env, $this->needEscaping($env)); } elseif ($node instanceof Twig_Node_Block) { @@ -45,8 +45,13 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface return $node; } - protected function escapeNode(Twig_Node $node, Twig_Environment $env) + protected function escapeNode(Twig_Node $node, Twig_Environment $env, $type) { + if (false === $type) + { + return $node; + } + $expression = $node instanceof Twig_Node_Print ? $node->getExpression() : $node; if ($expression instanceof Twig_Node_Expression_Filter) @@ -83,25 +88,25 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface { foreach ($filter[1] as $j => $argument) { - $filters[$i][1][$j] = $this->escapeNode($argument, $env); + $filters[$i][1][$j] = $this->escapeNode($argument, $env, $type); } } $expression->setFilters($filters); - $expression->prependFilter($this->getEscaperFilter()); + $expression->prependFilter($this->getEscaperFilter($type)); return $node; } elseif ($node instanceof Twig_Node_Print) { return new Twig_Node_Print( - new Twig_Node_Expression_Filter($expression, array($this->getEscaperFilter()), $node->getLine()) + new Twig_Node_Expression_Filter($expression, array($this->getEscaperFilter($type)), $node->getLine()) , $node->getLine() ); } else { - return new Twig_Node_Expression_Filter($node, array($this->getEscaperFilter()), $node->getLine()); + return new Twig_Node_Expression_Filter($node, array($this->getEscaperFilter($type)), $node->getLine()); } } @@ -117,8 +122,8 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface } } - protected function getEscaperFilter() + protected function getEscaperFilter($type) { - return array('escape', array()); + return array('escape', array(new Twig_Node_Expression_Constant((string) $type, -1))); } } diff --git a/lib/Twig/TokenParser/AutoEscape.php b/lib/Twig/TokenParser/AutoEscape.php index 45e514a..8943e2e 100644 --- a/lib/Twig/TokenParser/AutoEscape.php +++ b/lib/Twig/TokenParser/AutoEscape.php @@ -18,12 +18,23 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser { throw new Twig_SyntaxError("Autoescape value must be 'on' or 'off'", $lineno); } + $value = 'on' === $value ? true : false; + + if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) + { + if (false === $value) + { + throw new Twig_SyntaxError(sprintf('Unexpected escaping strategy as you set autoescaping to off.', $lineno), -1); + } + + $value = $this->parser->getStream()->next()->getValue(); + } $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - return new Twig_Node_AutoEscape('on' === $value ? true : false, $body, $lineno, $this->getTag()); + return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag()); } public function decideBlockEnd($token) diff --git a/test/fixtures/tags/autoescape/strategy.test b/test/fixtures/tags/autoescape/strategy.test new file mode 100644 index 0000000..f3e09dd --- /dev/null +++ b/test/fixtures/tags/autoescape/strategy.test @@ -0,0 +1,11 @@ +--TEST-- +"autoescape" tag accepts an escaping strategy +--TEMPLATE-- +{% autoescape on js %}{{ var }}{% endautoescape %} + +{% autoescape on html %}{{ var }}{% endautoescape %} +--DATA-- +return array('var' => '
"') +--EXPECT-- +
\" +<br />" diff --git a/test/unit/integrationTest.php b/test/unit/integrationTest.php index 2ac44d7..f8baf68 100644 --- a/test/unit/integrationTest.php +++ b/test/unit/integrationTest.php @@ -51,7 +51,7 @@ class TestExtension extends Twig_Extension } } -$t = new LimeTest(61); +$t = new LimeTest(62); $fixturesDir = realpath(dirname(__FILE__).'/../fixtures/'); foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)