Nella mia app Web, l'utente può creare post sul blog. Quando visualizzo il post del blog, le nuove righe non vengono visualizzate perché non ho sostituito le nuove righe con i tag <br>
. Il problema è che ho attivato l'autoescaping su Jinja, quindi i tag <br>
sono sottoposti a escape. Non voglio disabilitare temporaneamente l'autoescaping, voglio consentire in particolare i tag <br>
. Come lo farei?Consentire tag <br> con Google App Engine e Jinja2
risposta
ho un'altra risposta che secondo me è il migliore. Inizialmente stavo semplicemente visualizzando la mia variabile post.content
così com'è, e le nuove righe non venivano conservate. Nessuna delle soluzioni qui ha funzionato (bene), e la mia soluzione pre era solo una soluzione rapida e aveva grossi problemi. Questa è la vera soluzione:
{% for line in post.content.splitlines() %}
{{line}}<br>
{% endfor %}
Ottima soluzione! – billwild
Grazie funziona! –
La soluzione era inserire i tag <pre></pre>
nell'area in cui avevo il contenuto.
Questa non è una soluzione eccezionale: pre ha implicazioni su altre cose, come il ritorno a capo. –
Il modo più semplice per farlo è quello di scappare dal campo, quindi aggiungere interruzioni di riga. Quando lo si inoltra a jinja, contrassegnarlo come sicuro in modo che non sia autoescapito.
È possibile utilizzare il filtro |safe
, o utilizzare i blocchi autoescape:
{% autoescape false %}
{{ content goes here }}
{% autoescape %}
Si potrebbe anche impostare autoescaping nel environment-False
.
Nel modello a oggetti, aggiungere una funzione come questa:
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>'))
Poi nel modello, basta chiamare che:
<p>{{ post.html_content() }}</p>
È possibile creare un filtro Jinja2:
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
È necessario aggiungere il filtro al vostro ambiente Jinja2 prima di poter utilizzare:
JINJA2_ENV.filters['nl2br'] = jinja2_filters.nl2br
Nel tuo modello puoi usare quel filtro:
{{post.content|nl2br}}
Ecco un filtro ha scritto da solo:
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
e aggiungere il filtro alla jinja2.Environment()
chiamando:
jinja_env.filters['nl2br'] = nl2br
Si noti che questo non è sicuro in quanto passa il contenuto HTML. Dovrebbe essere: risultato = escape (valore) .replace ("\ n", Markup ("
")) –
gpothier
Si noti che ho autoescape per impostazione predefinita, in modo da evitare di spedirlo in questa funzione, ma questo è quello che sto usando
def nl2br(value):
split = value.split('\n')
return jinja2.Markup('<br>').join(split)
poi, naturalmente,
jinja_env.filters['nl2br'] = nl2br
È possibile utilizzare una 'textarea' se si desidera rispettare le nuove linee. – bossylobster