* 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
* * 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;
);
}
- public function getDefaultStrategy()
+ public function getDefaultStrategy($filename)
{
+ if (is_callable($this->defaultStrategy)) {
+ return call_user_func($this->defaultStrategy, $filename);
+ }
+
return $this->defaultStrategy;
}
protected $blocks = array();
protected $safeAnalysis;
protected $traverser;
+ protected $defaultStrategy = false;
public function __construct()
{
*/
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);
*/
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));
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;
--- /dev/null
+<?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<br/ > foo<br/ >', $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;
+ }
+}