In my web app, the user can make blog posts. When I display the blog post, newlines aren\'t shown because I didn\'t replace the new lines with
tags.
Here's a filter wrote by myself:
import jinja2
@jinja2.evalcontextfilter
def nl2br(eval_ctx, value):
result = jinja2.escape(value).unescape().replace('\n', '<br>')
if eval_ctx.autoescape:
result = jinja2.Markup(result)
return result
And add the filter to the jinja2.Environment()
by calling:
jinja_env.filters['nl2br'] = nl2br
You can use the |safe
filter, or use the autoescape blocks:
{% autoescape false %}
{{ content goes here }}
{% autoescape %}
You could also set autoescaping in the environment to False
.
In your model object, add a function like this:
class Post(db.Model):
# ...
def html_content(self):
# Escape, then convert newlines to br tags, then wrap with Markup object
# so that the <br> tags don't get escaped.
def escape(s):
# unicode() forces the conversion to happen immediately,
# instead of at substitution time (else <br> would get escaped too)
return unicode(jinja2.escape(s))
return jinja2.Markup(escape(self.content).replace('\n', '<br>'))
Then in your template, just call that:
<p>{{ post.html_content() }}</p>
The easiest way to do this is to escape the field yourself, then add line breaks. When you pass it in in jinja, mark it as safe so it's not autoescaped.
Note that i have autoescape on by default, so I don't check it in this function, but this is what I'm using
def nl2br(value):
split = value.split('\n')
return jinja2.Markup('<br>').join(split)
then of course,
jinja_env.filters['nl2br'] = nl2br
I have another answer that I think is the best. Initially I was just displaying my variable post.content
as-is, and the newlines weren't being preserved. None of the solutions here worked (well), and my pre solution was just a quick fix and had major issues. This is the real solution:
{% for line in post.content.splitlines() %}
{{line}}<br>
{% endfor %}