Message Flashing

Good applications and user interfaces are all about feedback. If the userdoes not get enough feedback they will probably end up hating theapplication. Flask provides a really simple way to give feedback to auser with the flashing system. The flashing system basically makes itpossible to record a message at the end of a request and access it nextrequest and only next request. This is usually combined with a layouttemplate that does this. Note that browsers and sometimes web servers enforcea limit on cookie sizes. This means that flashing messages that are toolarge for session cookies causes message flashing to fail silently.

Simple Flashing

So here is a full example:

  1. from flask import Flask, flash, redirect, render_template, \
  2. request, url_for
  3.  
  4. app = Flask(__name__)
  5. app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
  6.  
  7. @app.route('/')
  8. def index():
  9. return render_template('index.html')
  10.  
  11. @app.route('/login', methods=['GET', 'POST'])
  12. def login():
  13. error = None
  14. if request.method == 'POST':
  15. if request.form['username'] != 'admin' or \
  16. request.form['password'] != 'secret':
  17. error = 'Invalid credentials'
  18. else:
  19. flash('You were successfully logged in')
  20. return redirect(url_for('index'))
  21. return render_template('login.html', error=error)

And here is the layout.html template which does the magic:

  1. <!doctype html>
  2. <title>My Application</title>
  3. {% with messages = get_flashed_messages() %}
  4. {% if messages %}
  5. <ul class=flashes>
  6. {% for message in messages %}
  7. <li>{{ message }}</li>
  8. {% endfor %}
  9. </ul>
  10. {% endif %}
  11. {% endwith %}
  12. {% block body %}{% endblock %}

Here is the index.html template which inherits from layout.html:

{% extends "layout.html" %}
{% block body %}
  <h1>Overview</h1>
  <p>Do you want to <a href="{{ url_for('login') }}">log in?</a>
{% endblock %}

And here is the login.html template which also inherits fromlayout.html:

{% extends "layout.html" %}
{% block body %}
  <h1>Login</h1>
  {% if error %}
    <p class=error><strong>Error:</strong> {{ error }}
  {% endif %}
  <form method=post>
    <dl>
      <dt>Username:
      <dd><input type=text name=username value="{{
          request.form.username }}">
      <dt>Password:
      <dd><input type=password name=password>
    </dl>
    <p><input type=submit value=Login>
  </form>
{% endblock %}

Flashing With Categories

Changelog

New in version 0.3.

It is also possible to provide categories when flashing a message. Thedefault category if nothing is provided is 'message'. Alternativecategories can be used to give the user better feedback. For exampleerror messages could be displayed with a red background.

To flash a message with a different category, just use the second argumentto the flash() function:

flash(u'Invalid password provided', 'error')

Inside the template you then have to tell theget_flashed_messages() function to also return thecategories. The loop looks slightly different in that situation then:

{% with messages = get_flashed_messages(with_categories=true) %}
  {% if messages %}
    <ul class=flashes>
    {% for category, message in messages %}
      <li class="{{ category }}">{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

This is just one example of how to render these flashed messages. Onemight also use the category to add a prefix such as<strong>Error:</strong> to the message.

Filtering Flash Messages

Changelog

New in version 0.9.

Optionally you can pass a list of categories which filters the results ofget_flashed_messages(). This is useful if you wish torender each category in a separate block.

{% with errors = get_flashed_messages(category_filter=["error"]) %}
{% if errors %}
<div class="alert-message block-message error">
  <a class="close" href="#">×</a>
  <ul>
    {%- for msg in errors %}
    <li>{{ msg }}</li>
    {% endfor -%}
  </ul>
</div>
{% endif %}
{% endwith %}