37

I was playing around with flask when I came across an odd problem with the '\n' character. it dosen't seem to have an effect in my browser, I tried putting
in there but it didn't work, any ideas?

from flask import Flask
from flask import render_template
test=Flask(__name__)
@test.route('/')
def root():
    str='yay\nsuper'
    return str
test.run(debug=True)
ollien
  • 3,946
  • 9
  • 32
  • 55

5 Answers5

45

So it turns out that flask autoescapes html tags. So adding the <br> tag just renders them on screen instead of actually creating line breaks.

There are two workarounds to this:

  1. Break up the text into an array

    text = text.split('\n')
    

    And then within the template, use a for loop:

    {% for para in text %}
        <p>{{para}}</p>
    {% endfor %}
    
  2. Disable the autoescaping

    First we replace the \n with <br> using replace:

    text = text.replace('\n', '<br>')
    

    Then we disable the autoescaping by surrounding the block where we require this with

    {% autoescape false %}
        {{text}}
    {% endautoescape %}
    

    However, we are discouraged from doing this:

    Whenever you do this, please be very cautious about the variables you are using in this block.

I think the first version avoids the vulnerabilities present in the second version, while still being quite easy to understand.

24

Newlines only have an effect on HTML rendering in specific cases. You would need to use an HTML tag representing a newline, such as <br/>.

def root():
    str='yay<br/>super'
    return str
ʇsәɹoɈ
  • 21,294
  • 7
  • 52
  • 59
David Robinson
  • 74,512
  • 15
  • 159
  • 179
  • This is correct, but if you wouldn't mind, if I was putting this into a block element how would I do this? – ollien Sep 03 '12 at 08:23
  • What do you mean by a block element? – David Robinson Sep 03 '12 at 08:24
  • 1
    for example, if I were to put a variable like this {% block content %} {{stuffs}} {% endblock %} – ollien Sep 03 '12 at 08:27
  • Where do you need to put the `
    `, you're asking? It would go wherever you'd usually put the newline.
    – David Robinson Sep 03 '12 at 08:29
  • Oddly, it just prints out the actual
    I'm asking if there is a way to fix this Maybe I wasn't clear it would be something like `return render_template('index.html',stuffs=list')` and in the HTML `{%block content%} {{stuffs}} {%endblock%}`
    – ollien Sep 03 '12 at 08:31
  • Exactly- it does print out the `
    `, which will be rendered in your web browser as a newline.
    – David Robinson Sep 03 '12 at 08:32
  • 6
    No, actually it is printing out the `
    ` for me, screenshots: http://grab.by/fOTO EDIT:the H1 was a test for the HTML tags, but it was the same with the br
    – ollien Sep 03 '12 at 08:34
  • Do you have ` ` at the head of the document, and `` tags surrounding it? – David Robinson Sep 03 '12 at 08:36
  • I'd suggest asking this as a new question, including all details of how the page is served and what browser you're using. The fact that the

    tags don't work indicate it's not specific to
    .

    – David Robinson Sep 03 '12 at 08:56
  • 2
    Since this is marked as the correct answer... @ollien is experiencing standard Jinja2 behavior. The answer by Samarth addresses this issue. – Neal Gokli Oct 31 '17 at 23:40
12

In case someone end up here like me, and doesn't want to use {% autoescape false %}, for safety reasons, nor braking up the text which might be inconvenient in some cases, I found a good alternative here:

from flask import Markup
value = Markup('First line.<br>Second line.<br>')

and then in the jinja template:

{{ value }}
Zep
  • 1,434
  • 12
  • 19
2
  1. works for me and preserves security

I would suggest <br> rather than <p>

{% for para in text %}
    {{para}}<br>
{% endfor %}

then result is less bulky

  • Why does using
    preserve security but not

    ?

    – a3y3 Jun 22 '19 at 19:24
  • I think what he means by that is that it maintains security just as much as using `

    `, but it is less bulky. [It directly addresses the answer from Samarth](https://stackoverflow.com/a/41694784/2648551)
    – colidyre Mar 06 '20 at 21:06
2

I come late to the party, but here's my solution.
HTML has a <pre> tag which can prove useful in this situation.

<pre>{{ your_text }}</pre>

This tag tells the browser not to automatically adjust spacing and line breaks.
To learn more about this tag check this guide out.

Nicholas Obert
  • 485
  • 1
  • 6
  • 13