In a little wiki I’ve been playing with I’ve been trying out little ideas that I’ve had but haven’t had a place to actually implement them. One is how notification messages work. I’m sure other people have done the same thing, but I thought I’d describe it anyway.
A common pattern is to accept a POST request and then redirect the user to some page, setting a status message. Typically the status message is either set in a cookie or in the session, then the standard template for the application has some code to check for a message and display it.
The problem with this is that this breaks all caching — at any time any page can have some message injected into it, basically for no reason at all. So I thought: why not do the whole thing in Javascript? The server will set a cookie, but only Javascript will read it.
The code goes like this; on the server (easily translated into any framework):
resp.set_cookie('flash_message', urllib.quote(msg))
I quote the message because it can contain characters unsafe for cookies, and URL quoting is a particularly easy quoting to apply.
Then I have this Javascript (using jQuery):
$(function () { // Anything in $(function...) is run on page load var flashMsg = readCookie('flash_message'); if (flashMsg) { flashMsg = unescape(flashMsg); var el = $('<div id="flash-message">'+ '<div id="flash-message-close">'+ '<a title="dismiss this message" '+ 'id="flash-message-button" href="#">X</a></div>'+ flashMsg + '</div>'); $('a#flash-message-button', el).bind( 'click', function () { $(this.parentNode.parentNode).remove(); }); $('#body').prepend(el); eraseCookie('flash_message'); } });
Note that I’ve decided to treat the flash message as HTML. I don’t see a strong risk of injection attack in this case, though I must admit I’m a little unclear about what the normal policies are for cross-domain cookie setting.
I use these cookie functions because oddly I can’t find cookie handling functions in jQuery. It’s always weird to me how primitive document.cookie is. Anyway, CSS looks like this:
#flash-message { margin: 0.5em; border: 2px solid #000; background-color: #9f9; -moz-border-radius: 4px; text-align: center; } #flash-message-close { float: right; font-size: 70%; margin: 2px; } a#flash-message-button { text-decoration: none; color: #000; border: 1px solid #9f9; } a#flash-message-button:hover { border: 1px solid #000; background-color: #009; color: #fff; }
This doesn’t have non-Javascript fallback, but I think that’s okay. This isn’t something that a spider would ever see (since spiders shouldn’t be submitting forms that result in update messages). Accessible browsers generally implement Javascript so that’s also not particularly a problem, though there may be additional hints I could give in CSS or Javascript to help make this more readable (if there’s a message, it should probably be the first thing read on the page).
Another common component of pages that varies separate from the page itself is logged-in status, but that’s more heavily connected to your application. Get both into Javascript and you might be able to turn caching way up on a lot of your pages.