44

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
  • 4,418
  • 9
  • 35
  • 58

6 Answers6

52

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.

Samarth Hattangady
  • 696
  • 1
  • 7
  • 10
25

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Ɉ
  • 22,757
  • 7
  • 55
  • 61
David Robinson
  • 77,383
  • 16
  • 167
  • 187
  • 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
  • 7
    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
17

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,541
  • 13
  • 21
8

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
  • 1,235
  • 1
  • 13
  • 29
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
1

Easiest way to do this

  1. Create your template filter
@app.template_filter(name='linebreaksbr')
def linebreaksbr_filter(text):
    return text.replace('\n', '<br>')
  1. Add this to your template
{{ someText|linebreaksbr }}

This will replace every "\n" character in your text with <br>.

Lakshyaraj Dash
  • 153
  • 1
  • 7