Monthly Archives: August 2010

User communication with Django Messages and jGrowl

Like any good web application, I wanted stocklotstv/vidjyo to have a method of sending messages to the user. Simple stuff like ‘invalid username and password’ or a friendly greeting when the user succeeded in logging in, that sort of thing.

This requirement has now been added to django with the inclusion of django.contrib.messages in version 1.2. There has been a messaging framework included in django.contrib.auth since early days, but there are situations when you don’t want to use the native auth system, but you do need messaging, so it has been repackaged and extended as a standalone contribution.

The instructions for adding messages to your application are documented at Django Advent
Using the code is pretty simple. Add django.contrib.messages to your view or function and pass messages into the request context:

message.info(request, 'You have logged in')

and make sure that you are sending the request context to your templates (you *are* sending the request context to your templates aren’t you? It should be the default action in my opinion, but hey, that’s me, what do I know).

The template example at Django Advent is pretty simple -put this code somewhere in your templates:

{% if messages %}
    <ul class="messages">
        {% for message in messages %}
            <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
{% endif %}

However, I, and probably you, want to have system messages on most, if not all of our pages, so if you have a standard template layout, with a base template that includes the page metadata, and blocks or includes for header, footer and content, put the code in the html body, below your header but above your content.
What you get is an unsorted list of system messages at the top of your page, which probably isn’t what you want.

You could have some fun with CSS and turn your list into a menu or a sequence of messages, but a more common method of display these days, in the civilised worlds of Linux and Mac OS X at least, is to display the messages as bubbles, usually in the corner of the screen. In OS X, this is enabled by a system called Growl, which provides cross platform messaging with a very nice UI. On the web, it has been emulated with a couple of the better javascript libraries and as I have been mostly working with jQuery, I found jGrowl.

This is pretty simple to get working by following the demos, but they only cover getting messages by clicking on a link. What we want is for the messages to pop up when the page loads. This is where jQuery’s

$(document).ready(function())

comes in. This loads any script item in it when the document model is ready (sorry if that’s not wholly accurate, but that’s how I read it). Drupal has a jGrowl module that provides messaging in this way, so with a bit of code reading and lateral thinking, I came up with this:

{% if messages %}
<link href="/media/css/jquery.jgrowl.css" type="text/css" rel="stylesheet" media="screen" />
	<script type="text/javascript">
	(function($) {
		$(document).ready(function(){
			{% for message in messages %}
				$.jGrowl("{{ message }}");
			{% endfor %}
		});
	})(jQuery);
</script>

{% endif %}

Put simply, if there are messages in the request context, the browser will pass them into jGrowl and display them. There is no styling there at the moment, so they pop up at top right of the screen as white text on a black background. To save browser resources I also don’t load the stylesheet unless there are messages.
My next step is going to be to set the default position to centre and possibly to redesign the layout. jGrowl has a theme setting which is defined using css classes, and the django message object has the tags attribute which is based on standard system message codes such as info, error and warning which the documentation suggests that you also use as CSS classes . You might be able to see where this is going. I will return to this when I’ve got it working and can provide a couple of screenshots.

In conclusion, django.messages is a useful addition to Django and, combined with some judicious jQuery-based scripting, creates an attractive method of communicating with your users.