Search code examples
phpsessionsmartyflash-message

Implementing a flash message on a Smarty site?


I'm trying to implement a "Flash Message" (a little message that'll show on the top on the "next" request, saying things like "record saved"), in a PHP site that has pretty messy code and uses Smarty.

The best I could come up with is:

  1. I set the message in a specially named variable in $_SESSION
  2. My "header" template checks for that variable ($smarty.session.flash) and if it's set, it shows the message
  3. After rendering, and only if a template was rendered, clear the $_SESSION variable.

My problem is with #3. The only way I could find of doing it was registering an output filter with Smarty:

function smarty_outputfilter_flashmessage($tpl_output, $smarty) {
    if (isset($_SESSION['flash'])) {
        $_SESSION['flash'] = "";
    }
    return $tpl_output;
}

$smarty->register_outputfilter("smarty_outputfilter_flashmessage");

The problem with that is that, if a template has sub-templates, that function gets called for each sub-template. Also, there are a number of places in the code that do

$variable = $smarty->fetch('something.tpl')

which also triggers my outputfilter.

When that happens, the output filter clears the session variable before the header template is rendered, and the message is lost.

Any ideas/suggestions on how to better do this?

Is there some kind of PHP built-in callback to execute a custom function when a request "ends"? (With that, I could add the clearing there, and have the output_filter simply set a variable to show whether something was rendered)

Ideally, something that gets called unless the code calls die()?

Or, of course, another completely different and better way to do this?

Thanks!
Daniel


Solution

  • I haven't seriously used PHP or Smarty in ages, but instead of trying to guess when a template was rendered, can't you do a Smarty function that does something like:

    function smarty_function_pop_flash_message($params, $smarty) {
        $msg = "";
        if (isset($_SESSION['flash'])) {
            $msg = $_SESSION['flash'];
            $_SESSION['flash'] = "";
        }
        return $msg;
    }
    

    And then in the template where you show this message:

    {if isset($smarty.session.flash) && $smarty.session.flash != ''}
        <div id="flash">{pop_flash_message}</div>
    {/if}