2012-05-03 13 views
9

W mojej aplikacji internetowej użytkownik może pisać posty na blogu. Gdy wyświetlam wpis na blogu, znaki nowej linii nie są wyświetlane, ponieważ nie zastąpiłem nowych linii znacznikami <br>. Problem polega na tym, że w Jinji zmieniłem autoescaping, więc tagi <br> są chronione. Nie chcę tymczasowo wyłączać autoescaping, chcę konkretnie dopuszczać tagi <br>. Jak to zrobić?Zezwalanie na znaczniki <br> z Google App Engine i Jinja2

+0

Możesz użyć 'textarea', jeśli chcesz, aby znaki nowej linii były szanowane. – bossylobster

Odpowiedz

26

mam inną odpowiedź, która moim zdaniem jest najlepszy. Początkowo wyświetlałem moją zmienną post.content tak jak jest, a nowe znaki nie były zachowywane. Żadne z rozwiązań tutaj nie działało (dobrze), a moje wcześniejsze rozwiązanie było po prostu szybką naprawą i miało poważne problemy. To jest prawdziwe rozwiązanie:

{% for line in post.content.splitlines() %} 
    {{line}}<br> 
{% endfor %} 
+1

Świetne rozwiązanie! – billwild

+0

Dzięki temu działa! –

-1

Rozwiązaniem było umieszczenie tagów <pre></pre> wokół obszaru, w którym miałem zawartość.

+2

To nie jest świetne rozwiązanie - pre ma wpływ na inne rzeczy, takie jak zawijanie linii. –

-1

Najprostszym sposobem, aby to zrobić, jest samodzielne wyjście z pola, a następnie dodanie podziałów linii. Kiedy przekażesz go w jinja, oznacz go jako bezpieczny, aby nie był autoescaped.

2

Można użyć filtru |safe lub użyj autoescape bloków:

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

Można również ustawić autoescaping w environment do False.

+2

Ale co, jeśli to nie jest bezpieczne? – LtWorf

+0

@LtWorf ma rację. Powinieneś założyć, że wprowadzona przez użytkownika zawartość jest złośliwa.Większość z nich nie będzie, ale nie chcesz, aby jeden zły facet wstawiał JavaScript, który daje Twoim użytkownikom wirusy. -1 – jpmc26

2

w modelu obiektu, dodać funkcję tak:

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>')) 

Następnie w szablonie, wystarczy zadzwonić, że:

<p>{{ post.html_content() }}</p> 
0

Można utworzyć filtr 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 

trzeba dodać filtr do jinja2 Środowiska, zanim będzie można go używać:

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

W swoim szablonie możesz użyć tego filtra:

{{post.content|nl2br}} 
0

Oto filtr napisał o sobie:

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 

i dodać filtr do jinja2.Environment() pod numerem:

jinja_env.filters['nl2br'] = nl2br 
+0

Należy pamiętać, że jest to niebezpieczne, ponieważ przechodzi treść HTML. Powinno być: result = escape (value) .replace ("\ n", Markup ("
")) – gpothier

0

Zauważ, że mam autoescape domyślnie, więc nie sprawdzić w funkcja ta, ale to jest to, czego używam

def nl2br(value): 
    split = value.split('\n') 
    return jinja2.Markup('<br>').join(split) 

wtedy oczywiście

jinja_env.filters['nl2br'] = nl2br