# -*- coding: utf-8 -*-
"""
Flash Messages
==============
One-time notification of users in web applications.
The common use case for flash messages is to issue informational, warning or
error messages after a POST request has been made and to show them after a
subsequent HTTP redirect. The latter is done to ensure a POST request
(modifying data on the server) isn't sent again when the user reloads a page.
If the page to (which the user is redirected to) is reloaded, the message
won't be shown again.
A session object is used to store one or more messages. This implementation
utilizes ``collections.defaultdict`` (which was introduced in Python 2.5) and
the Werkzeug_ WSGI toolkit.
In the actual snippet code, the import ``request`` object is expected to be a
``werkzeug.wrappers.BaseRequest`` (or subclass) wrapper_ instance, provided as
`context local`_, and needs to have a ``werkzeug.contrib.sessions`` session
store attached to it as attribute named ``session``. All this can also be
adapted to work with other components, such as the Beaker_ session middleware
or the Paste_ or WebOb_ WSGI toolkits.
To retrieve waiting flash messages and remove them from the session object
afterwards::
import flash
flash_messages = flash.get_messages(True)
They can be then passed on to a template engine. An example of how to show
waiting messages in a Genshi_ (layout) template::
<ul id="flash" py:if="flash_messages">
<py:for each="category, messages in flash_messages.iteritems()">
<li py:for="message in messages" class="${category}">${message}</li>
</py:for>
</ul><!-- /#flash -->
Cascading Stylesheets (CSS) and some nice icons can then be used to style the
messages according to their respective types.
.. _Werkzeug: http://werkzeug.pocoo.org/
.. _wrapper: http://werkzeug.pocoo.org/documentation/wrappers
.. _context local: http://werkzeug.pocoo.org/documentation/local
.. _Beaker: http://beaker.groovie.org/
.. _Paste: http://pythonpaste.org/
.. _WebOb: http://pythonpaste.org/webob/
.. _Genshi: http://genshi.edgewall.org/
:Copyright: 2008 Jochen Kupperschmidt
:Date: 16-May-2008
:License: MIT
"""
from collections import defaultdict
from example_application import request
def get_messages(clear=False):
"""Return messages as dictionary with categories as keys."""
messages = request.session.get('flash', {})
if clear:
clear_messages()
return messages
def clear_messages():
"""Clear all messages."""
request.session['flash'] = defaultdict(list)
def _set_message(category, message):
"""Set a message."""
if not 'flash' in request.session:
request.session['flash'] = defaultdict(list)
request.session['flash'][category].append(message)
request.session.modified = True
def set_error(message):
"""Set an error message."""
_set_message('error', message)
def set_warning(message):
"""Set a warning message."""
_set_message('warning', message)
def set_notice(message):
"""Set a notice message."""
_set_message('notice', message)