Search code examples
smartysmarty3

How to make Smarty automatically escape all template variables but ignore captures


I want to automatically escape all template variables, that is, I want them to be escaped without having to write |escape all the time. Thus I enabled the $escape_html option.

However, apparently Smarty treats variables created using {capture} the same way, even though these can be considered trusted input. We have a lot of those in our codebase and having to write nofilter everywhere is almost as annoying as having to write |escape.

Surely there must be a solution for this? Or are $escape_html and {capture} incompatible?


Solution

  • $escape_html and {capture} are not incompatible by definition, no.

    $escape_html (as well as a {setfilter} and default_modifiers) suffer from the problem of not knowing the context of a variable. They are executed whenever a variable is supposed to be output. There is no "where did that variable come from" tracking, that would allow the Smarty compiler to realize "hey, variable $foo was defined through a capture and has thus already been escaped, don't escape it again". It even gets worse when considering scenarios like "within the capture group escape for javascript, the resulting string escape as html".

    Right now your options are fairly limited:

    1. |escape everthing that needs escaping
    2. nofilter everything that should not be escaped (again)

    I'll discuss this issue with Smarty's compiler maintainer to figure out what we could possibly do. But, should we find a solution, it would be introduced with Smarty 3.2 - the earliest. So for now, escape/nofilter manually.