Severity codes in user messages

 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
from django import template
from django.template import Variable

register = template.Library()

class UserMessageNode(template.Node):
  """The template processor uses this to hold a user message"""
  def __init__(self, message):
    self.message = Variable(message)

  def render(self, context):
    try:
      message = self.message.resolve(context)
      if message[-4:].isdigit():
        error_code = message[-4:]
        message = message[:-4]
      else:
        error_code = ''

      if error_code == '0000':
        return u'<div class="success">' + message + u'</div>'
      if error_code == '0001':
        return u'<div class="error">' + message + u'</div>'
      if error_code == '0002':
        return u'<div class="notice">' + message + u'</div>'
      else:
        return u'<div class="error">' + message + u'</div>'

    except template.VariableDoesNotExist:
      return ''

@register.tag(name='render_user_message')
def render_user_message(parser, token):
  """A tag that renders a user message differently depending on the severity of it."""
  try:
    message = token.split_contents()[1]
  except ValueError:
    raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
  return UserMessageNode(message)

More like this

  1. Cookie based flash errors and notices (a la Rails) by alexk 4 years, 8 months ago
  2. "Partial Templates" - an alternative to "include" by vigrid 4 years, 3 months ago
  3. AjaxForm Base Classes by btaylordesign 2 years, 2 months ago
  4. isoutc template filter by japerk 4 years, 1 month ago
  5. Mod to allow simple_tag to access context by leaf 4 years, 8 months ago

Comments

david_bgk (on January 19, 2009):

Why do you use those cryptic error codes instead of prepended SUCCESS:, ERROR: and so on?

#

cconnell (on February 3, 2009):

Using the numbers makes it easy to know which characters are the error code, since there are always 4 characters plus the two brackets around them. Using that knowledge I just count back from the end of the string. I suppose one could use string codes, but I was being a little lazy.

#

willhardy (on February 10, 2009):

Ahh, I said the same thing as david_bgk on your blog, but I'll post here too. Strings are a good idea, david_bgk's uppercase chars are a better ide... your test could then use isupper()

Also, it would be more "pythonic" to use a dict for the CSS class mapping instead of a string of if elif elif elif statements.

Eg

CODES = {'ERROR': 'error', 'SUCCESS': 'success', 'NOTICE': 'notice' }
MARKUP = u'<div class="%s">%s</div>'

message_part, error_code = message.strip().rsplit(' ',1)

try:
  return MARKUP % (CODES.get(error_code), message_part)
except KeyError:
  return MARKUP % ('error', message)

(NB You'll have to cover the possible ValueError from the rsplit if there is no space in message :-)

#

TehOne (on March 17, 2009):

This is how I have chosen to implement my version of this. I made mine a simpletag because I didn't need direct access to the variable or context from the template. From the docs: "When your template tag does not need access to the current context, writing a function to work with the input values and using the simple_tag helper is the easiest way to create a new tag."

@register.simple_tag
def render_user_message(message):
    CODES = {'ERROR': 'error', 'SUCCESS': 'success', 'NOTICE': 'notice'}
    MARKUP = u'<div class="%s">%s</div>'

    message_part, message_type = message.strip().rsplit(' ', 1)

    try:
        return MARKUP % (CODES.get(message_type), message_part)
    except KeyError:
        return MARKUP % ('notice', message)

#

(Forgotten your password?)