Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2 escape all HTML but img, b, etc

Jinja2 automatically escapes all HTML tags, but I want to not escape some tags (like img, b, and some others). How can I do it?

like image 866
sashab Avatar asked Jan 23 '12 18:01

sashab


3 Answers

You can write your own filter. The scrubber library is pretty good at cleaning up HTML. The filter will need to wrap the returned string in jinja2.Markup so the template will not re-escape it.

Edit: a code example

import jinja2
import scrubber

def sanitize_html(text):
    return jinja2.Markup(scrubber.Scrubber().scrub(text))

jinja_env.filters['sanitize_html'] = sanitize_html
like image 159
Alex Morega Avatar answered Sep 26 '22 06:09

Alex Morega


You'll want to parse the input on submission using a white list approach - there are several good examples in this question and viable options out there.

Once you have done that, you can mark any variables that will contain HTML that should not be escaped with the safe filter:

{{comment|safe}}
like image 44
Sean Vieira Avatar answered Sep 23 '22 06:09

Sean Vieira


The Bleach library can do very well.

For example, assuming the variable 'jinja_env' is in scope:

from bleach import clean
from markupsafe import Markup

def do_clean(text, **kw):
    """Perform clean and return a Markup object to mark the string as safe.
    This prevents Jinja from re-escaping the result."""
    return Markup(clean(text, **kw))

jinja_env.filters['clean'] = do_clean

Then in a template you might have something like:

<p>{{ my_variable|clean(tags=['img', 'b', 'i', 'em', 'strong'], attributes={'img': ['src', 'alt', 'title', 'width', 'height']}) }}</p>

You can also use a callable (instead of a list) in the attributes, allowing more thorough validation of the attributes (e.g. checking that src provides a valid URL). Documentation shows an example.

like image 21
David Avatar answered Sep 26 '22 06:09

David