made auto-escaping more configurable with the new is_escaper option

git-svn-id: http://svn.twig-project.org/trunk@186 93ef8e89-cb99-4229-a87c-7fa0fa45744b
This commit is contained in:
fabien
2009-12-15 07:15:46 +00:00
parent dfca5a153a
commit 2f0d54d0c9
7 changed files with 61 additions and 35 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ environment constant by the "needs_environment" option:
'even' => new Twig_Filter_Function('twig_is_even_filter'),
'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
* changed the automatic-escaping rules to be more sensible (the documentation lists all the rules)
* changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
* improved the filter system to allow object methods to be used as filters
* changed the Array and String loaders to actually make use of the cache mechanism
* included the default filter function definitions in the extension class files directly (Core, Escaper)
+4
View File
@@ -341,6 +341,10 @@ The escaping rules are implemented as follows:
{{ var|foo(bar) }} {# bar will be escaped #}
{{ var|foo(bar|safe) }} {# bar won't be escaped #}
* Automatic escaping is not applied if one of the filter in the chain has the
`is_escaper` option set to `true` (this is the case for the built-in
`escaper`, `safe`, and `urlencode` filters for instance).
### Sandbox Extension
The `sandbox` extension can be used to evaluate untrusted code. Access to
+36 -23
View File
@@ -115,25 +115,6 @@ method:
}
}
The `Twig_Filter` classes take flags as their last argument. For instance, if
you want access to the current environment instance in your filter, set the
`needs_environment` option to `true`:
[php]
$filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true));
Twig will then pass the current environment as the first argument to the
filter call:
[php]
function twig_compute_rot13(Twig_Environment $env, $string)
{
// get the current charset for instance
$charset = $env->getCharset();
return str_rot13($string);
}
Parameters passed to the filter are available as extra arguments to the
function call:
@@ -143,11 +124,8 @@ function call:
-
[php]
function twig_compute_rot13(Twig_Environment $env, $string, $prefix = '')
function twig_compute_rot13($string, $prefix = '')
{
// get the current charset for instance
$charset = $env->getCharset();
return $prefix.str_rot13($string);
}
@@ -207,6 +185,41 @@ Using methods for filters is a great way to package your filter without
polluting the global namespace. This also gives the developer more flexibility
at the cost of a small overhead.
### Environment aware Filters
The `Twig_Filter` classes take options as their last argument. For instance, if
you want access to the current environment instance in your filter, set the
`needs_environment` option to `true`:
[php]
$filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true));
Twig will then pass the current environment as the first argument to the
filter call:
[php]
function twig_compute_rot13(Twig_Environment $env, $string)
{
// get the current charset for instance
$charset = $env->getCharset();
return str_rot13($string);
}
### Automatic Escaping
If automatic escaping is enabled, the main value passed to the filters is
automatically escaped. If your filter acts as an escaper, you will want the
raw variable value. In such a case, set the `is_escaper` option to `true`:
[php]
$filter = new Twig_Filter_Function('urlencode', array('is_escaper' => true));
>**NOTE**
>The parameters passed as extra arguments to the filters are not affected by
>the `is_escaper` option and they are always escaped according to the
>automatic escaping rules.
Overriding default Filters
--------------------------
+3 -3
View File
@@ -70,7 +70,7 @@ class Twig_Extension_Core extends Twig_Extension
'floor' => new Twig_Filter_Function('twig_floor_filter'),
// encoding
'urlencode' => new Twig_Filter_Function('twig_urlencode_filter'),
'urlencode' => new Twig_Filter_Function('twig_urlencode_filter', array('is_escaper' => true)),
// string filters
'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)),
@@ -93,8 +93,8 @@ class Twig_Extension_Core extends Twig_Extension
'items' => new Twig_Filter_Function('twig_get_array_items_filter'),
// escaping
'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_escaper' => true)),
'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_escaper' => true)),
);
if (function_exists('mb_get_info'))
+1 -1
View File
@@ -54,7 +54,7 @@ class Twig_Extension_Escaper extends Twig_Extension
public function getFilters()
{
return array(
'safe' => new Twig_Filter_Function('twig_safe_filter'),
'safe' => new Twig_Filter_Function('twig_safe_filter', array('is_escaper' => true)),
);
}
+6
View File
@@ -24,6 +24,7 @@ abstract class Twig_Filter
{
$this->options = array_merge(array(
'needs_environment' => false,
'is_escaper' => false,
), $options);
}
@@ -33,4 +34,9 @@ abstract class Twig_Filter
{
return $this->options['needs_environment'];
}
public function isEscaper()
{
return $this->options['is_escaper'];
}
}
+10 -7
View File
@@ -46,19 +46,22 @@ class Twig_NodeTransformer_Escaper extends Twig_NodeTransformer
if ($expression instanceof Twig_Node_Expression_Filter)
{
// don't escape if escape has already been called
// or if we want the safe string
if ($expression->hasFilter('escape') || $expression->hasFilter('safe'))
{
return $node;
}
// don't escape if the primary node of the filter is not a variable
$nodes = $expression->getNodes();
if (!$nodes[0] instanceof Twig_Node_Expression_Name)
{
return $node;
}
// don't escape if there is already an "escaper" in the filter chain
$filterMap = $this->env->getFilters();
foreach ($expression->getFilters() as $filter)
{
if (isset($filterMap[$filter[0]]) && $filterMap[$filter[0]]->isEscaper())
{
return $node;
}
}
}
elseif (!$expression instanceof Twig_Node_Expression_Name)
{