Hi everyone,
I've done some more work on my alternative to turbogears.flash(), and
it's pretty decent as this point (at least I think so), and it might
be useful for others.
What it does:
* Multiple messages
* Different classes of message (warning, error, etc.), which can be
styled accordingly.
* HTML in messages (only if explicitly allowed, and not the default)
* Logger-like invocation: f.warning("The sky is falling!")
* Hideable messages (tell a message to go away once and you'll never
see it again)
It works based on sessions, rather than a cookie. To use it in any
controller, you just instantiate a Flash2 object and call one of the
methods to add a message:
f = Flash2()
f.info("Hello, world!")
You can even do it all at once if you're only going to have one
message:
Flash2().info("Hello, world -- in one line!")
Here's a more complete example controller:
@expose(template=".templates.test_flash2")
def test_flash2(self):
f2 = Flash2()
f2.info("This is the first message. It's an info.")
f2.warning("This is the second message. It's a warning.",
hideable=True)
f2.error("This is the third message. It's an error!", growl=True)
f2.info("This is the fourth message. It's an info.",
hideable=True)
f2.warning("This is the fifth message. It has some <strong>HTML</
strong> in it! <a href='http://www.google.com/'>Google</a> rocks.",
html=True)
f2.warning("This is the sixth message. It is NOT an HTML message,
but yet it has some <strong>HTML</strong> in it! <a href='http://
www.google.com/'>Google</a> rocks.")
f2.ok("Super!")
f2.add_message("There's a <strong>bug</strong> on this page.",
'bug', True)
f2.add_message("Heavy construction underway!", 'construction')
f2.add_message("There's a feed here somewhere.", 'feed')
return dict()
You can see the results in a screenshot here:
http://www.anseljh.com/code/flash2/flash2.png
(Note that the fourth message doesn't show up; the "Hide" link was
previously clicked.)
Here's how to implement it.
(1) Add the Flash2Message and Flash2 classes to your controllers.py:
class Flash2Message:
def __init__(self, msg, cls='info', html=False, hideable=False):
self.message = msg
self.css = cls
self.html = html
self.hideable = hideable
self.md5 = md5.md5(self.message).hexdigest()
class Flash2:
def __init__(self):
self.messages = []
self.messages_dict = {'info':[], 'warning':[], 'error':[], 'ok':
[]}
self.generator = self._generator() # use f2.generator.next() to
get messages
self.next = self._generator # next() method to make class iterable
def __iter__(self):
return self.generator
def add_message(self, msg, cls, html=False, growl=False,
hideable=False):
m = Flash2Message(msg, cls, html, hideable)
self.messages.append(m)
if cls not in self.messages_dict:
self.messages_dict[cls] = []
self.messages_dict[cls].append(m)
cherrypy.session['flash2'] = self # stick the generator in the TG/
CP session; use it in master template
def _generator(self):
"""
Build a generator for getting messages from a Flash2 instance
"""
while(1):
try:
m = self.messages.pop(0) # pop the first Flash2Message in the
list
yield m
except IndexError:
raise StopIteration
def info(self, msg, html=False, hideable=False, growl=False):
self.add_message(msg, 'info', html, growl, hideable)
def warning(self, msg, html=False, hideable=False, growl=False):
self.add_message(msg, 'warning', html, growl, hideable)
def error(self, msg, html=False, hideable=False, growl=False):
self.add_message(msg, 'error', html, growl, hideable)
def ok(self, msg, html=False, hideable=False, growl=False):
self.add_message(msg, 'ok', html, growl, hideable)
# ignore all the 'growl' stuff -- that's remnants from debugging
(2) Add this at the top of your master.kid template -- after the
DOCTYPE but before the <html> tag:
<?python
from cherrypy import request as cp_request
from cherrypy import session as cp_session
?>
(3) Add this to your master template wherever you want the flash
messages to show up:
<div py:if="cp_session.has_key('flash2')" id="flash2">
<div py:for="message in cp_session.get('flash2')"
class="message ${message.css}" id="flash2_${message.md5}"
py:if="'flash2_hide_'+message.md5 not in cp_request.simple_cookie">
<div py:if="message.hideable" class="hide">
<a href="#" onclick="javascript:
MochiKit.Visual.fade('flash2_${message.md5}', {'duration':0.25});
document.cookie='flash2_hide_${message.md5}=True';">Hide</a>
</div>
<span py:if="message.html"
py:content="XML(message.message)" />
<span py:if="not message.html"
py:content="message.message" />
</div>
</div>
(4) Put some styles in your master stylesheet. Here's what I have:
#flash2 .message {
/* base styles for all flash2 messages */
border-width: 3px;
border-style: solid;
margin: .5em;
padding: .5em;
}
#flash2 .error {
/*background: url(/static/images/warning.gif) left center no-
repeat;*/
background-color: #fdd; /* red */
border-color: #f00;
}
#flash2 .warning {
background-color: #ffd; /* yellow? */
border-color: #ff0;
}
#flash2 .info {
padding-left: 50px;
background: url(/static/images/info.png) left center no-repeat;
background-color: #eeeeff;
border-color: #bbd;
}
#flash2 .ok {
padding-left: 50px;
background: url(/static/images/ok.png) left center no-repeat;
background-color: #cceecc;
border-color: #81db28;
}
#flash2 .bug {
padding-left: 50px;
background: url(/static/images/bug001.gif) .2em center no-repeat;
background-color: #fdd; /* red */
border-color: #f00;
}
#flash2 .construction {
padding-left: 50px;
/*background: url(/static/images/construction1.gif) .2em center no-
repeat;*/
background-color: #ffd; /* yellow? */
border-color: #ff0;
}
#flash2 .feed {
padding-left: 50px;
background: url(/static/images/feed-icon-24x24.png) .2em center no-
repeat;
background-color: #ffd; /* yellow? */
border-color: #ff8509;
}
#flash2 .message .hide {
float: right;
font-size: 85%;
}
And that's it.
Comments? Suggestions for improvement?
-Ansel
P.S. The "Hide" link includes a MochiKit 1.4 call
(MochiKit.Visual.fade()), which I don't think will work on a stock TG
1.0.x installation. You can replace that part with some other DOM
scripting to hide the message element, but that's left as an exercise
for the reader.
P.P.S. Because it depends on sessions, you'll have to enable them in
your config files. See: http://docs.turbogears.org/1.0/Sessions
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---