Allow custom autoescape functions as result of the autoescape function parameter for the Environment #1377
Description
I am currently trying to build an app that generates PDFs based on LaTeX imports.
For this I use django extensions that renders the LaTeX file and also provides the possibility to escape single variables.
Every variable that is given to the templates system can be modified by the users, so I would need to escape every single occurrence, which is error prone.
Therefore using the autoescape feature of Jinja would be great.
Reading #503, which was closed unsuccessfully there are currently two way to implement this kind of autoescape
- Writing an Extension that overwrites the
filter_stream
and and adds a| my_custom_filter
add the end of every variable. (used by JinjaSQL) - Overwrite the Jinja default escape function by a custom one (used by Jinja Vanish)
Both solution feel hacky and unstable.
That why I would suggest to expand the autoescape
parameter from the Environment to accept not only functions returning a boolean but also a custom escape function.
Like this
from typing import Union, Callable
from jinja2 import Environment, PackageLoader
def do_latex_escape(value: str) -> str:
return (
value.replace("&", "\\&")
.replace("$", "\\$")
.replace("%", "\\%")
.replace("#", "\\#")
.replace("_", "\\_")
.replace("{", "\\{")
.replace("}", "\\}")
)
def smart_autoescape(template_name: str) -> Union[bool, Callable[[str], str]] :
if template_name.endswith(('.html', '.htm', '.xml')):
return True # Use Default Escape Function
if template_name.endswith(('.latex', '.tex', '.luatex')):
return do_latex_escape # for LaTeX Files escape LaTeX
return False
env = Environment(autoescape=smart_autoescape,
loader=PackageLoader('mypackage'))
I would expect the following to happen in the above case:
- Given a HTML template
- Autoescape and everything as normal
- Given a template with any latex extension
- autoescape is enabled`
- the function
do_latex_escape
is wrapped to it does not escape safe text (example - the default escape filter (
| e
) and (| escape
) is replaced by thedo_latex_escape
filter - autoescaping is done with the new filter
- Everything else
- Autoescape is disabled
What do you think about the suggestion? If you like it, I would try to create a PR.
If I understand it correctly Jinja Vanish already provides some good starting point for it.