$anything_for_layout: Making HTML from the View available to the layout
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.
Download code
And now to put a subheader into your layout, you can just write a view like this -
Download code
Enjoy ;)
Download code
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 CodeDownload 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
Comment
1 Nice helper
Comment
2 alternative
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';
Comment
3 Not working for me...
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 :-)
Comment
4 reply to Not working for me
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
Comment
5 my bad
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 :-)
Comment
6 Works great in 1.2 beta
Comment
7 (double post)
Comment
8 Great
This should definitely be included in the core, it's surely a common thing to want to do.