Flash Message Template Tag

  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 6 years, 9 months ago
  2. Cookie based flash errors and notices (a la Rails) by alexk 5 years, 7 months ago
  3. Notifications Middleware for Session-Backed Messages by tclineks 5 years, 7 months ago
  4. SectionedForm by marinho 5 years, 10 months ago
  5. Templatetag startswith + message tuned by io_error 5 years, 10 months 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)

#

(Forgotten your password?)