Login

Flash Message Template Tag

Author:
rtconner
Posted:
July 16, 2007
Language:
Python
Version:
.96
Tags:
template flash message
Score:
6 (after 6 ratings)

Flash message add-on for Django. Uses sessions. Behavior is such that you set a flash message in a view. That message is stored in the sesssion. Then whenever it is that the message gets displayed, it is removed from the session (never to be heard from again)

Installation:

In your settings, enable the following items.

TEMPLATE_CONTEXT_PROCESSORS django.core.context_processors.request

MIDDLEWARE_CLASSES django.contrib.sessions.middleware.SessionMiddleware

Then put it into a file called flash.py in your templatetags directory.

Usage:

It's pretty simple. Do something like this in your view ..

>>>request.session['flash_msg'] = 'Your changes have been save'
>>>request.session['flash_params'] = {'type': 'success'}

And maybe put something like this in your template

{% load flash %}
{% flash %}
  <h2>{{ params.type }}</h2>
  {{ msg }}
{% endflash %}

It also support a flash template, you can specify a file FLASH_TEMPLATE in your settings file and then that file will be rendered with msg and params as available variable. Usage for this would simply be {% flash_template %} and then you gotta make a template file that does whatever you like.

Outside of that just be aware you need the Django session middleware and request context installed in your app to use this.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
To function this requires the following to be installed:

TEMPLATE_CONTEXT_PROCESSORS
django.core.context_processors.request

MIDDLEWARE_CLASSES
django.contrib.sessions.middleware.SessionMiddleware

@author: Robert Conner (rtconner)
"""

from django import template
from django.template import resolve_variable, Context
import datetime
from django.template.loader import render_to_string
from django.contrib.sessions.models import Session
from django.conf import settings

register = template.Library()


def session_clear(session):
    """
    Private function, clear flash msgsfrom the session
    """
    try:
        del session['flash_msg']
    except KeyError:
        pass
    
    try:
        del session['flash_params']
    except KeyError:
        pass
    
    # Save changes to session
    if(session.session_key):
        Session.objects.save(session.session_key, session._session,
            datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE))


class RunFlashBlockNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist
        
    def render(self, context):
        
        session = context['request'].session
        ret = None
        if session.get('flash_msg', False):
            ret = {'msg': session['flash_msg']}
            if 'flash_params' in session:
                ret['params'] = session.get('flash_params', False)
            session_clear(session);

        if ret is not None:
            return self.nodelist.render(ret)
        return ''


class RunFlashTemplateNode(template.Node):
    def __init__(self):
        pass
    
    def render(self, context):
        session = context['request'].session
        if session.get('flash_msg', False):
            ret = {'msg': session['flash_msg']}
            if 'flash_params' in session:
                ret['params'] = session.get('flash_params', False)
                
            session_clear(session);
            try:
                template = settings.FLASH_TEMPLATE
            except AttributeError:
                template = 'elements/flash.html'
            return render_to_string(template, dictionary=ret) 
        return ''

@register.tag(name="flash_template")
def do_flash_template(parser, token):
    """
    Call template if there is flash message in session
        
    Runs a check if there is a flash message in the session.
    If the flash message exists it calls settings.FLASH_TEMPLATE
    and passes the template the variables 'msg' and 'params'.
    Calling this clears the flash from the session automatically
    
    To set a flash msg, in a view call:
    request.session['flash_msg'] = 'sometihng'
    request.session[flash_'params'] = {'note': 'remember me'}
    
    In the template {{ msg }} and {{ params.note }} are available
    """
    return RunFlashTemplateNode()

@register.tag(name="flash")
def do_flash_block(parser, token):
    """
    A block section where msg and params are both available.
    Calling this clears the flash from the session automatically
    
    If there is no flash msg, then nothing inside this block
    gets rendered
    
    Example:
    {% flash %}
        {{msg}}<br />
        {{params.somekey}}
    {% endflash %}
    """
    nodelist = parser.parse(('endflash',))
    parser.delete_first_token()
    return RunFlashBlockNode(nodelist)

More like this

  1. Extended rails flash implementation by miracle2k 7 years, 11 months ago
  2. Cookie based flash errors and notices (a la Rails) by alexk 6 years, 9 months ago
  3. Notifications Middleware for Session-Backed Messages by tclineks 6 years, 10 months ago
  4. Templatetag startswith + message tuned by io_error 7 years ago
  5. SectionedForm by marinho 7 years ago

Comments

JustinHoMi (on February 1, 2008):

I think this code may have been responsible for user-login problems. Occasionally my application would start rejecting all users from login, and I'd have to restart the app. After removing this code from my application the problem went away. However, that wasn't the only change to my code, so I can't be sure. But it was the only change directed towards solving the login problem.

#

plucas (on May 19, 2008):

I had to make the following change starting at line 57, for this to work with the latest django:

if ret is not None:
        context.update(ret)
        return self.nodelist.render(context)

#

Please login first before commenting.