Saturday, December 15, 2007

Try Zend Framework vol.8 "Using Layout with ViewRenderer"

**************************************** Notice ****************************************
"Zend_Layout" is out after version 1.5 !!
It's much more flexible and easy to use . So you should read the documentation and use it. :-)
**************************************** Notice ****************************************

When you use Zend Framework, you probably write full HTML for each action in your controllers.
It's kind of wasting time to write HTML for every template. isn't is?
And if you need to put additional code like css or javascript, you need to write same code for every template.
I think the concept of "Layout" is very powerful and useful, so I wrote ViewRenderer which can handle layout.

First you need to create a new ViewRenderer which extends Zend_Controller_Action_Helper_ViewRenderer. And just change a little on postDispatch() and add some methods.

library/Hoge/Controller/Action/Helper/ViewRenderer.php
<?php
require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';

/**
* View script integration
*/
class Hoge_Controller_Action_Helper_ViewRenderer extends Zend_Controller_Action_Helper_ViewRenderer
{
/**
* postDispatch - auto render a view
* @return void
*/
public function postDispatch()
{
if ($this->getFrontController()->getParam('noViewRenderer')) {
return;
}

if (!$this->_neverRender
&& !$this->_noRender
&& (null !== $this->_actionController)
&& $this->getRequest()->isDispatched()
&& !$this->getResponse()->isRedirect())
{
if($this->hasViewLayout()) {
$this->render();
$this->view->contens = $this->getResponse()->getBody();
$this->getResponse()->clearBody();
$this->render($this->getViewLayout(), null, true);
} else {
$this->render();
}
}
}

/**
* if layout is sat.
* @return bool
*/
function hasViewLayout()
{
if ($this->getActionController()->layout) {
return true;
}
return false;
}

/**
* Get layout template
* @return string
*/
function getViewLayout()
{
return $this->getActionController()->layout;
}
}


Next, you need to add Views' Script Path.
www/index.php
$view = new Zend_View();
$view->setScriptPath(dirname(dirname(__FILE__)) . '/application/views/scripts/');
$view->addScriptPath(dirname(dirname(__FILE__)) . '/application/views/layouts/');

so now, it will look for templates not only scripts but also layouts directory.
*Don't forget to set setScriptPath, too. Otherwise it only see layouts directory.
Then, use new ViewRenderer which you just made.
www/index.php
$viewRenderer = new Hoge_Controller_Action_Helper_ViewRenderer($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

To use it you nedd to set layout. Set $layout variable and put the name of layout template.

appplication/controllers/HogeController.php
class HogeController extends Zend_Controller_Action
{
var $layout = 'default';


And make layout template
application/views/layouts/default.phtml
<html>
<head>
</head>
<body>
<?= $this->contens ?>
</body>
</html>


That's it. :-)

Be careful, under these case like bellow, ViewRenderer will not work. :P

Call setNoRender() in the Controller.
application/controllers/HogeController.php
$this->_helper->viewRenderer->setNoRender();


Call render() on purpose.
application/controllers/HogeController.php
function indexAction()
{
$this->render();
}


Set noViewRenderer.
www/index.php
$front = Zend_Controller_Front::getInstance();
$front->setParam('noViewRenderer', true);


(weight 87.0kg BMI 29%)

Labels:

0 Comments:

Post a Comment

<< Home