$anything_for_layout: Making HTML from the View available to the layout

By Rob Conner aka "rtconner"
Did you ever have a side navigation that you wanted to change based upon changes in the view? Using this helper, you can write HTML and other output for display in the layout. The output itself is written in the your view and then transfered to the layout.
This is pretty simple to use. Instead of explaining it all and it's many many varied uses and advantages, I'll just give a quick demo.

An Example

This is a quick and dirty layout:
Download code <html>
    <head>
        <title><?=$title_for_layout;?>        
    </head>
    <body>
        
        <h2>This is a Website header</h2>
        <? $layout->output($subheader_for_layout);?>

        <hr>

        <?php echo $content_for_layout;?>

        <hr>
        <h3>A footer would go here</h3>

    </body>
</html>


And now to put a subheader into your layout, you can just write a view like this -
Download code <?=$layout->blockStart('subheader');?>
    <h4>This is a page Sub Heading</h4>
<?=$layout->blockEnd();?>

This would be the main content of the current page.


Enjoy ;)


The Code

Here is the complete Helper Code
Download code <?php
/**
 * LayoutHelper
 * This Helper provides a few functions that can be used to assist the layout.
 * 
 * @author Robert Conner <rtconner>
 */

class LayoutHelper extends AppHelper {
    
    var 
$__blockName null;
    
    
/**
     * Start a block of output to display in layout
     *
     * @param  string $name Will be prepended to form {$name}_for_layout variable
     */
    
function blockStart($name) {

        if(empty(
$name))
            
trigger_error('LayoutHelper::blockStart - name is a required parameter');
            
        if(!
is_null($this->__blockName))
            
trigger_error('LayoutHelper::blockStart - Blocks cannot overlap');

        
$this->__blockName $name;
        
ob_start();
        return 
null;
    }
    
    
/**
     * Ends a block of output to display in layout
     */
    
function blockEnd() {
        
$buffer = @ob_get_contents();
        @
ob_end_clean();

        
$out $buffer
            
        
$view =& ClassRegistry::getObject('view');
        
$view->viewVars[$this->__blockName.'_for_layout'] = $out;
        
        
$this->__blockName null;
    }
    
    
/**
     * Output a variable only if it exists. If it does not exist you may optionally pass
     * in a second parameter to use as a default value.
     * 
     * @param mixed $variable Data to ourput
     * @param mixed $defaul Value to output if first paramter does not exist
     */
    
function output(&$var$default=null) {
        if(!isset(
$var) or $var==null) {
            if(!
is_null($default)) 
                echo 
$default;
        } else
            echo 
$var;    
    }
    
}

?>

Comments 516

CakePHP team comments Author comments

Comment

1 Nice helper

You call it "Layout" but "PartialLayout" should more appropriate, no ?
posted Thu, Aug 30th 2007, 04:48 by Fab

Comment

2 alternative

Just in case you don't need this level of control, it can be really simple to get variables in the layout.

Just set any variable with the suffix "_for_layout".

eg: $this->set('anything_for_layout','1234');

Also - the $title_for_layout can be modified within a controller by modifying the $pageTitle variable.

eg: var $pageTitle = 'This Controller';
eg: $this->pageTitle.= ' | This Action';
posted Sun, Sep 2nd 2007, 12:56 by alan blount

Comment

3 Not working for me...

Hiya, I'd like to use this code, but it's not working for me as of yet. Firstly, It seems that the helper should start with:

class LayoutHelper extends Helper {

instead of:

class LayoutHelper extends AppHelper {

Having made this change, it runs wihtrout error, but nothing is output to my view. I am right in thinking that I use the:

<?=$layout->blockStart('subheader');?> etc

code in my views?

Any help greatly appreciated,

dan :-)
posted Wed, Sep 5th 2007, 05:03 by Dan Ballance

Comment

4 reply to Not working for me

@Dan
Sorry, his really hasn't been tested outside my system and setup and version of PHP. I haven't a clue how it will work on PHP4 or cake 1.1.

So.. to clarify,
- this code assumes you have the Output Controll lib installed (http://us.php.net/manual/en/ref.outcontrol.php)
- I am pretty sure $layout->output() will only work with PHP5.
- Also I am fairly sure this only works with cake 1.2

You dont need to use the output function, its just handy in case the ${blah}_for_layout varaible you are using does not exist.

Hope this helps.

-Rob
posted Wed, Sep 5th 2007, 14:45 by Rob Conner

Comment

5 my bad

My apologies Rob, I'm using 1.1. My mistake, sorry <blush>

In the end I have coded something that does the job in my application, but it's not as modular as your code which is a shame. Hopefully I will migrate to 1.2 at some point, but since I use cake for my work, there's not enough documentation right now for me to take that step yet - I'm not brave enough lol

peace to you,

dan :-)
posted Sun, Sep 9th 2007, 13:55 by Dan Ballance

Comment

6 Works great in 1.2 beta

A very nice and handy helper! Should be included in the core. Works pretty well for me in Cake 1.2 beta
posted Thu, Mar 27th 2008, 15:07 by Stefan Vetter

Comment

7 (double post)

The connection got lost, so I made a double post accidentially! How can I delete it, btw? Seems that the Bakery is missing this function..
posted Thu, Mar 27th 2008, 15:11 by Stefan Vetter

Comment

8 Great

Very useful helper.

This should definitely be included in the core, it's surely a common thing to want to do.
posted Fri, May 16th 2008, 04:46 by Nick H

Login to Submit a Comment