46

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) 

6 Answers 6

57

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.

Sign up to request clarification or add additional context in comments.

2 Comments

{% autoescape false %} ! That's what I was looking for, thanks.
The link is dead. Here's the one for Flask 1.1: flask.palletsprojects.com/en/1.1.x/templating/…
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 

10 Comments

This is correct, but if you wouldn't mind, if I was putting this into a block element how would I do this?
What do you mean by a block element?
for example, if I were to put a variable like this {% block content %} {{stuffs}} {% endblock %}
No, actually it is printing out the <br/> for me, screenshots: grab.by/fOTO EDIT:the H1 was a test for the HTML tags, but it was the same with the br
Since this is marked as the correct answer... @ollien is experiencing standard Jinja2 behavior. The answer by Samarth addresses this issue.
|
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 }} 

2 Comments

how Can I do this in django?
Sorry, I have never used Django!
9

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.

Comments

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

2 Comments

Why does using <br> preserve security but not <p>?
I think what he means by that is that it maintains security just as much as using <p>…</p>, but it is less bulky. It directly addresses the answer from Samarth
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>.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.