Zend Framework: Part 3 – Zend_Layout

Zend_Layout implements a classic Two Step View pattern, allowing developers to wrap application content within another view, usually representing the site template.

The main goals of Zend_Layout are as follows:

  • Automate selection and rendering of layouts when used with the Zend Framework MVC components
  • Provide separate scope for layout related variables and content
  • Allow configuration, including layout name, layout script resolution (inflection), and layout script path
  • Allow disabling layouts, changing layout scripts, and other states; allow these actions from within action controllers and view scripts
  • Follow same script resolution rules (inflection) as the ViewRenderer, but allow them to also use different rules
  • Allow usage without Zend Framework MVC components
Two Step View
Two Step View

We will focus on using Zend_Layout with the Zend Framework MVC. First we need to create a layout script:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <?= $this->headTitle() ?>
  <?= $this->headScript() ?>
  <?= $this->headStyle() ?>
</head>
<body>
 
  <?= $this->render('header.phtml') ?>    
 
  <div id="navigation"><?= $this->placeholder('navigation') ?></div>    
 
  <div id="content"><?= $this->layout()->content ?></div>    
 
  <?= $this->render('footer.phtml') ?>
</body>
</html>

Zend_Layout::startMvc() creates an instance of Zend_Layout with any optional configuration you provide it. It then registers a front controller plugin that renders the layout with any application content once the dispatch loop is done, and registers an action helper to allow access to the layout object from your action controllers. Additionally, you may at any time grab the layout instance from within a view script using the layout view helper.

In an action controller, you may then access the layout instance as an action helper, $this->_helper->layout. In your view scripts, you can then access the layout object via the layout view helper. This view helper is slightly different than others in that it takes no arguments, and returns an object instead of a string value. This allows you to immediately call methods on the layout object, $this->layout()->setLayout(‘navigation’). At any time, you can fetch the Zend_Layout instance registered with the MVC via the getMvcInstance() static method, $layout = Zend_Layout::getMvcInstance().

Zend_Layout’s front controller plugin has one important feature in addition to rendering the layout: it retrieves all named segments from the response object and assigns them as layout variables, assigning the ‘default’ segment to the variable ‘content’. This allows you to access your application content and render it in your view scripts.

As an example, let’s say your code first hits LoginController::loginAction(), which renders some content to the default response segment, and then forwards to NavigationController::navigationAction(), which renders content to the ‘navigation’ response segment. Finally, you forward to PageController::pageAction() and fetch a page, but render those to the default response segment as well (which appends content to that segment). Your view script could then render each separately:

<body>
  <!-- navigation response segment;  renders navigation -->
  <div id="navigation"><?= $this->layout()->navigation ?></div>
  <!-- default response segment;  renders login and page-->
  <div id="content"><?= $this->layout()->content ?></div>
</body>

Leave a Reply