How to display html content through flask messages?
Question:
I understand that flash()
takes only string and displays that in the redirected page.
I m trying to send html through flash
message = "<h1>Voila! Platform is ready to used</h1>"
flash(message)
return render_template('output.html')
output.html
<div class="flashes">
{% for message in get_flashed_messages()%}
{{ message }}
{% endfor %}
</div>
But it is displaying as string <h1>Voila! Platform is ready to used</h1>
is there any way to overcome this.
Answers:
Use the safe
filter:
<div class="flashes">
{% for message in get_flashed_messages()%}
{{ message|safe }}
{% endfor %}
</div>
Where possible, a secure approach is to wrap your string in a Markup object before passing it to the template:
Python code:
from flask import Markup
message = Markup("<h1>Voila! Platform is ready to used</h1>")
flash(message)
return render_template('output.html')
Jinja2 Template:
<div class="flashes">
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</div>
Using {{message|safe}}
will work, but also opens up the door for an attacker to inject malicious HTML or Javascript into your page, also known an an XSS attack. More info here if you’re interested.
For cases where you might want to control the CSS applied depending on the status of message (Success | Error), the following code might be useful:
{% for category, msg in get_flashed_messages(with_categories=true) %}
<div class="alert {{ category }} alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
{{ msg|safe }}
</div>
{% endfor %}
Another way is to call render_template
to the external HTML file and passing that to Markup
class.
main/routes.py
from flask import render_template, flash, Markup
from . import blueprint
@blueprint.route("/user")
def user():
flash(Markup(render_template("templates/user.html", name="John Doe"))
return render_template("templates/home.html")
templates/user.html
<h1>User: {{ name }}</h1>
I understand that flash()
takes only string and displays that in the redirected page.
I m trying to send html through flash
message = "<h1>Voila! Platform is ready to used</h1>"
flash(message)
return render_template('output.html')
output.html
<div class="flashes">
{% for message in get_flashed_messages()%}
{{ message }}
{% endfor %}
</div>
But it is displaying as string <h1>Voila! Platform is ready to used</h1>
is there any way to overcome this.
Use the safe
filter:
<div class="flashes">
{% for message in get_flashed_messages()%}
{{ message|safe }}
{% endfor %}
</div>
Where possible, a secure approach is to wrap your string in a Markup object before passing it to the template:
Python code:
from flask import Markup
message = Markup("<h1>Voila! Platform is ready to used</h1>")
flash(message)
return render_template('output.html')
Jinja2 Template:
<div class="flashes">
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</div>
Using {{message|safe}}
will work, but also opens up the door for an attacker to inject malicious HTML or Javascript into your page, also known an an XSS attack. More info here if you’re interested.
For cases where you might want to control the CSS applied depending on the status of message (Success | Error), the following code might be useful:
{% for category, msg in get_flashed_messages(with_categories=true) %}
<div class="alert {{ category }} alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
{{ msg|safe }}
</div>
{% endfor %}
Another way is to call render_template
to the external HTML file and passing that to Markup
class.
main/routes.py
from flask import render_template, flash, Markup
from . import blueprint
@blueprint.route("/user")
def user():
flash(Markup(render_template("templates/user.html", name="John Doe"))
return render_template("templates/home.html")
templates/user.html
<h1>User: {{ name }}</h1>