-->

Allowing
tags with Google App Engine and Jinj

2019-02-12 16:28发布

问题:

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 <br> tags. The problem is that I've turned autoescaping on in Jinja, so <br> tags are escaped. I don't want to temporarily disable autoescaping, I want to specifically allow <br> tags. How would I do this?

回答1:

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 %}


回答2:

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.



回答3:

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>


回答4:

You can create a jinja2 filter:

import re
from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')

@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n')
                          for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

You need to add the filter to your jinja2 Environment before you can use it:

JINJA2_ENV.filters['nl2br'] = jinja2_filters.nl2br

In your template you can use that filter:

{{post.content|nl2br}}


回答5:

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


回答6:

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


回答7:

The solution was to put <pre></pre> tags around the area where I had the content.



回答8:

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.