Multiple flashes with different classes

by personman
There were a couple of things I didn't like about using $this->Session->setFlash(), so I wrote my own method for saving flashes and helper for displaying them.
While it's a step up from the old flash method, using $this->Session->setFlash() has two problems:

  1. You can only do one flash message.
  2. It's always the same color. I want to use red for problems, green for success and grey for neutral status messages.

I added this to my AppController:

Controller Class:

<?php 
class AppController extends Controller
{
  
  var 
$helpers = array('Flash');
  
/*
   * Add a message to the messages array in the session like this:
   * $this->flash( 'You are logged in.', 'success' );
   */ 
  
function flash$message$class 'status' )
  {
    
$old $this->Session->read('messages');
    
$old[$class][] = $message;
    
$this->Session->write'messages'$old );
  }

}
?>

Then I added this to app/views/helpers/flash.php:

Helper Class:

<?php 
class FlashHelper extends Helper
{
  var 
$helpers = array( 'Session' );
  function 
show()
  {
    
// Get the messages from the session
    
$messages $this->Session->read'messages' );
    
$html '';
    
    
// Add a div for each message using the type as the class
    
foreach ($messages as $type => $msgs)
    {
      foreach (
$msgs as $msg)
      {
        if (!empty(
$msg)) {
          
$html .= "<div class='$type'><p>$msg</p></div>";
        }        
      }
    }
    
$html .= "</div>";
    
    
// Clear the messages array from the session
    
$this->Session->del'messages' );
    
    return 
$this->output$html );
  }
  
}
?>

Now in my controllers I do this:


$this->flash( 'Something normal happened.' );
$this->flash( 'Something good happened.', 'success' );
$this->flash( 'Danger!', 'error' );

And in my layout I added this:


<?php echo $flash->show(); ?>

Now you can us css to style your messages. The classes are 'status', 'success' and 'error'.

This is inspired by the set_message() function in Drupal.

Report

More on Helpers

Tags

Advertising

Comments

  • sethcardoza posted on 05/19/09 08:09:36 AM
    I know this code is a few years old, but I still don't see a way to set multiple flash messages with core components without having to specify a unique key for each message.

    I'd like to submit an update for this though. I've tweaked it a little to be a little more robust.
  • euromark posted on 07/13/08 03:50:19 PM
    es müssen übrigens alle header(), die caching unterbinden, in die bootstrap.php (oder dergleichen),
    weil sonst machner browser die meldungen noch wo anzeigt, wo sie gar nich mehr sein sollten...
    hatte ne weile gebraucht diesen fehler zu finden...

    sonst wundert sich echt noch jemand über meldungen an der falschen stellen
    also einfach einbauen, dann passts
  • euromark posted on 07/12/08 10:28:26 PM
    i thought, this little "bug" already found its way into the core.. (almost 1 year later)
    but it doesnt seem like that..

    i tried to solve this using the functions already present. but i would have to change core files. thats no good.

    does your helper work on reload as well as without reloading?

    mark
  • personman posted on 10/01/07 10:30:24 AM
    Nate said (in PM):I don't know who approved this article, but if you had read the API for either setFlash() or flash(), you'd see that what you're doing here is completely redundant, since all this and much more is already supported in the core framework.
    Nate, are you sure that the core provides this functionality? Please see my discussion with Christoph. I'll concede that it's generally better to use the default way of doing things and that the default way would work for me most of the time. But will anyone admit that I've added a bit of functionality, not to mention made the code required to set the message in the controller a bit shorter? You can say that the functionality is not an improvement, but it certainly makes it possible to do something that can't be done with the core method (set two messages without having different keys).

    And yes, I looked at the API. It wasn't very clear what the key does without looking at the source code. But I could tell from testing that the second message overwrites the first.
  • personman posted on 10/01/07 10:29:57 AM
    I did try the default way and it works fine. For the 99% of the time when I only set one message, it wouldn't be a problem. If I did try to set two, then it would fail silently and the first message would never get to the user. My method requires a bit less code and I think it's more flexible, or at least it works the way I want it to.
  • preloader posted on 10/01/07 10:12:47 AM
    ... will be overwritten.

    Why not simply try it? ;-)

    Also: $session->flash('someKey'); returns false, if no message was set, so you could do "conditional messages" with different keys.

    Regards, Christoph
  • personman posted on 10/01/07 09:57:28 AM
    Thanks for explaining. But what if I do

    $this->Session->setFlash('Your user profile is incomplete.', 'default', array(), 'errorKey');

    $this->Session->setFlash('Your hair is on fire.', 'default', array(), 'errorKey');

    Will both messages show? Or will the second overwrite the first? I generally won't show more than one message at a time, but I'd like to be able to set messages without worrying about whether I've already done it.
  • preloader posted on 10/01/07 08:20:57 AM
    In your controller:

    $this->Session->setFlash('my error message', 'default', array(), 'errorKey');
    $this->Session->setFlash('my success message', 'default', array(), 'successKey');

    In your view:

    $session->flash('errorKey');
    $session->flash('successKey');

    API is your friend:
    http://api.cakephp.org/1.2
    Search for SessionComponent and SessionHelper.

    Regards, Christoph :-)
  • personman posted on 10/01/07 07:45:12 AM
    Sorry for posting code that isn't needed. I would prefer to use the built-in way of doing this. Can someone show me how to use it? I tried using setFlash() multiple times in one controller, but the second time always overwrote the first message. What was I doing wrong?
  • kabturek posted on 09/26/07 01:11:03 PM
    You can specify a layout for the flash message (second param of Session::setFlash) :)
  • preloader posted on 09/26/07 03:29:57 AM
    Why not use the $key-param in SessionComponent::setFlash() and SessionHelper::flash()???

    Regards, Christoph
  • nate posted on 09/20/07 11:12:01 PM
    I don't know who approved this article, but if you had read the API for either setFlash() or flash(), you'd see that what you're doing here is completely redundant, since all this and much more is already supported in the core framework.
login to post a comment.