Mojimi
Mojimi

Reputation: 3171

Jinja2 mark specific HTML tag as safe

I'm aware of both safe and escape filters in jinja, but I couldn't find a solution for my problem.

I have the following string :

mystring = """<script>alert('I'm unsafe')</script>

I just entered a new line


Two new lines now!"""

I want to use it in a <p> tag showing the newlines properly :

<p>{{mystring | replace('\n', '<br>')}}</p>

This doesn't work as Jinja2 automatically escapes HTML tags, but if I do :

<p>{{mystring | replace('\n', '<br>') | safe }}</p>

It will then be unsafe.

What I have tried is :

<p>{{mystring | escape | replace('\n', '<br>') | safe }}</p>

But the above doesn't work, the <br>s are still escaped for some reason

How can I have the <br> tags not be escaped?

Upvotes: 5

Views: 1712

Answers (2)

Roberto Trani
Roberto Trani

Reputation: 1227

After reading @cizario's answer, I found the following solution not involving custom filters:

<p>{{mystring | replace('\n', '<br>' | safe) }}</p>

The problem highlighted by the question is that replace produces unsafe strings that will be escaped afterward. By telling to the template engine that our '<br>' strings are safe, we avoid that it escapes the line breaks produced by the replace filter.

Upvotes: 0

cizario
cizario

Reputation: 4254

to mark <br> tag as safe, the solution is to use a custom filter as described here

Here a small example filter that breaks a text into HTML line breaks and paragraphs and marks the return value as safe HTML string if autoescaping is enabled:

with some customization, you can adapt the logic to your case:

create filters.py (to make the application modular)

import re
from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(\n)')

@evalcontextfilter
def nl2br(eval_ctx, value):

    result = ''.join('%s' % p.replace('\n', Markup('<br>'))
        for p in _paragraph_re.split(escape(value)))

    if eval_ctx.autoescape:
        result = Markup(result)

    return result

and then in app.py

from flask import Flask

from .filters import nl2br

app = Flask(__name__)
[..]
app.jinja_env.filters['nl2br'] = nl2br

and then in you template

<p>{{ mystring | nl2br }}</p>

Upvotes: 2

Related Questions