added a way to dynamically change the auto-escaping strategy according to the template filename

This commit is contained in:
Fabien Potencier
2012-04-25 06:25:28 +02:00
parent 109db731ca
commit 1f00c33acd
5 changed files with 53 additions and 5 deletions
+1
View File
@@ -1,5 +1,6 @@
* 1.8.0 (2012-XX-XX)
* added a way to dynamically change the auto-escaping strategy according to the template "filename"
* changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html)
* added an embed tag
+1
View File
@@ -73,6 +73,7 @@ class Twig_Environment
* * false: disable auto-escaping
* * true: equivalent to html
* * html, js: set the autoescaping to one of the supported strategies
* * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename"
*
* * optimizations: A flag that indicates which optimizations to apply
* (default to -1 which means that all optimizations are enabled;
+5 -1
View File
@@ -54,8 +54,12 @@ class Twig_Extension_Escaper extends Twig_Extension
);
}
public function getDefaultStrategy()
public function getDefaultStrategy($filename)
{
if (is_callable($this->defaultStrategy)) {
return call_user_func($this->defaultStrategy, $filename);
}
return $this->defaultStrategy;
}
+11 -4
View File
@@ -21,6 +21,7 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
protected $blocks = array();
protected $safeAnalysis;
protected $traverser;
protected $defaultStrategy = false;
public function __construct()
{
@@ -37,7 +38,11 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
*/
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{
if ($node instanceof Twig_Node_AutoEscape) {
if ($node instanceof Twig_Node_Module) {
if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) {
$this->defaultStrategy = $defaultStrategy;
}
} elseif ($node instanceof Twig_Node_AutoEscape) {
$this->statusStack[] = $node->getAttribute('value');
} elseif ($node instanceof Twig_Node_Block) {
$this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
@@ -56,7 +61,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
*/
public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{
if ($node instanceof Twig_Node_Expression_Filter) {
if ($node instanceof Twig_Node_Module) {
$this->defaultStrategy = false;
} elseif ($node instanceof Twig_Node_Expression_Filter) {
return $this->preEscapeFilterNode($node, $env);
} elseif ($node instanceof Twig_Node_Print) {
return $this->escapePrintNode($node, $env, $this->needEscaping($env));
@@ -135,8 +142,8 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
return $this->statusStack[count($this->statusStack) - 1];
}
if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy()) {
return $defaultStrategy;
if ($this->defaultStrategy) {
return $this->defaultStrategy;
}
return false;
+35
View File
@@ -0,0 +1,35 @@
<?php
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase
{
public function testAutoescapeOption()
{
$loader = new Twig_Loader_Array(array(
'html' => '{{ foo }} {{ foo }}',
'js' => '{{ bar }} {{ bar }}',
));
$twig = new Twig_Environment($loader, array(
'debug' => true,
'cache' => false,
'autoescape' => array($this, 'escapingStrategyCallback'),
));
$this->assertEquals('foo&lt;br/ &gt; foo&lt;br/ &gt;', $twig->render('html', array('foo' => 'foo<br/ >')));
$this->assertEquals('foo\x3cbr\x2f \x3e foo\x3cbr\x2f \x3e', $twig->render('js', array('bar' => 'foo<br/ >')));
}
public function escapingStrategyCallback($filename)
{
return $filename;
}
}