Session-Based Flash Messages Look Better (CakePHP)

The CakePHP blog tutorial uses a rather archaic method of displaying user messages (like, “Your post has been saved.“) that needlessly breaks up the flow of your application. Rather than Cake’s typical method of displaying flash messages on a separate page (ugly), learn how to seamlessly display the same messages within your application and make your users clap with joy.

See What I Mean?

Let me show you exactly what I’m talking about using some screen shots I took of my own application.

These first two screen shots show the index page and post page of my news application:

(At the moment, nothing is posted on the index page.)
CakePHP Session-Based Messages - Part 1

(A typical form allows the user to post a new news article…)
CakePHP Session-Based Messages - Part 2

When we post a new news article, the typical Cake method is to display a flash message on a separate page, forcing the user to temporally leave your application. This method is distracting for the user and makes your application feel broken up. (To return to the news index page, the user is forced to click the “Your post has been saved” message.)

CakePHP Session-Based Messages - Part 3

Instead of the above method, let’s use the same messages in a Web 2.0 fashion. After a news article is posted, we can automatically redirect the user back to the index page AND display the message on the same page:

CakePHP Session-Based Messages - Part 4

See what I mean? Allow me to show you how it’s done…

Configure Your Layout

In order to display the awesome-web-2.0-styled messages, we need to add a line of code to your app/views/layouts/default.thtml page, above the code which displays your layout content:

<?php
   if ($session->check('Message.flash')): $session->flash(); endif; // this line displays our flash messages
   echo $content_for_layout;
?>

Configure Your Controller

Next comes the line you must add to your app/controllers/news_controller.php controller to display your message and redirect your user to a particular page:

function add() {
...
   if ($this->News->save($this->data)) {
      $this->Session->setFlash('Your post has been saved.');
      $this->redirect('/news/index');
      //$this->flash('The News has been saved', '/news/index'); // this was the old way of doing things... yuck
   }
}

All Done!

Now when a flash message is displayed, it’ll be placed in a div (directly above the layout content) for easy style manipulation:

<div id="flashMessage" class="message">Your post has been saved.</div>

Easy as cake. If you have any questions or suggestions, please post.

9 Comments so far

  1. links for 2008-01-15 « Richard@Home on January 14th, 2008

    [...] Session-Based Flash Messages Look Better (CakePHP) - Labs Flashier flash messages in CakePHP (tags: cakephp session flash) [...]

  2. leveille on January 20th, 2008

    I agree with your assessment that the use of the intermediate flash page intrudes into the normal application flow. I implement a technique whereby I create a flash element, and render this flash element at the top of my template.

    
    element('flash');
    
    

    The flash element consists of code to check whether or not the message being sent is an error, warning, or success:

    
       check('Message.err'))
          {
             echo '';
             $session->flash('err');
             echo '';
          }
    
       check('Message.warn'))
          {
             echo '';
             $session->flash('warn');
             echo '';
          }
    
       check('Message.succ'))
          {
             echo '';
             $session->flash('succ');
             echo '';
          }
    
    

    I also make use of these div’s for javascript feedback, which is why I don’t programmatically display the actual div/class. They’re always ready to be injected with user feedback. The p tags on the other hand are displayed when appropriate, as those are what get styled via css.

    In my controller I set the type of flash message and redirect to the appropriate location:

    
    $this->Session->setFlash('The lesson you have selected is unavailable or invalid.  Please try again.', null, null, 'err');
    $this->redirect(array('action'=>'index'));
    
    

    Just thought I would share. This technique may or may not be helpful to others.

  3. Djiize on January 23rd, 2008

    @leveille: or you can use the 2nd param of setFlash to specify a layout $this->Session->setFlash(’bad values’, ‘flash_err’)
    then create your layouts: flash_err.ctp, flash_warn.ctp, flash_succ.ctp
    and just call $session->flash() in you default layout
    Leave boring work to Cake, it exists for that ;)

  4. Jonah on June 22nd, 2008

    Thanks for the article and the comment from Djiize. I now know how to use the Session->setFlash() funtion!

  5. connector on June 24th, 2008

    Thanks for the nice tutorial. One question, can you tell my what wysiwy editor you used in the screenshots? Thanks!

  6. Koa on June 24th, 2008

    connector, I’m using TinyMCE as the WYSIWYG editor. Enjoy!

  7. deltawing1 on July 4th, 2008

    Thanks for this tutorial!

    Oh and thank you Djize! I’ve been needing exactly that technique :-)
    The elegant and “correct” way to do it.

  8. mark on July 16th, 2008

    I did find your posting very useful, although i created my own helper class “Flash” for this one.
    This was needed, because CakePHP is not able to put more then 1 Message of each category (error, success etc) in the SESSION.

    So if your app throws a second error somewhere, the first one will be deleted silently, which is really a problem at some points!

    I put them in an array, and therefore can store multiple ones, which are (by the helper) read out and displayed.

    Next thing i wanna build in, is a sorted display. Not random, but in the order of importance: Error -> Warning -> Success -> Info

Leave a Reply