2012-05-03 5 views
9

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

+0

È possibile utilizzare una 'textarea' se si desidera rispettare le nuove linee. – bossylobster

risposta

26

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

Ottima soluzione! – billwild

+0

Grazie funziona! –

-1

La soluzione era inserire i tag <pre></pre> nell'area in cui avevo il contenuto.

+2

Questa non è una soluzione eccezionale: pre ha implicazioni su altre cose, come il ritorno a capo. –

-1

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.

2

È possibile utilizzare il filtro |safe, o utilizzare i blocchi autoescape:

{% autoescape false %} 
{{ content goes here }} 
{% autoescape %} 

Si potrebbe anche impostare autoescaping nel environment-False.

+2

Ma cosa succede se non è sicuro? – LtWorf

+0

@LtWorf ha ragione. È necessario presumere che il contenuto inserito dall'utente sia dannoso.La maggior parte non lo sarà, ma non vuoi che quel malvagio inserisca JavaScript che offra virus ai tuoi utenti. -1 – jpmc26

2

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> 
0

È 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}} 
0

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 
+0

Si noti che questo non è sicuro in quanto passa il contenuto HTML. Dovrebbe essere: risultato = escape (valore) .replace ("\ n", Markup ("
")) – gpothier

0

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