Zend Framework provides the components Zend_View and Zend_Layout to facilitate developing the view layer of your application.
These components are light, powerful, and nifty – making it easy to alter behavior slightly to achieve different rendering strategies.
The primary strategy outlined by the framework
is the Two Step View pattern.
While the Two Step View pattern creates a reasonable paradigm for seperating layout presentation from page presentation, enabling
Three-level Inheritance allows for even better separation. In other words, using 3 Step Layouts is a possible and often necessary
investment to make when implementing front-ends in Zend Framework projects; they allow fine grain re-usability that provides
for a DRYer presentation layer.

Setting up 3 Step Layouts
Nothing extra is needed to implement this pattern, just Zend Framework.
Step 1 – The Wrapper
The first step is to create a wrapper. A wrapper is just a view, there’s nothing special about it.
Register your wrapper with Zend Framework by popping into application.ini and telling the Layout Resource that the wrapper
is the default layout, also specifying where to find it:
; application/configs/application.ini
resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"
resources.layout.layout = wrapper
As a general rule of thumb all view behavior that needs to happen on every request, regardless of which controller or module is being accessed, belongs in the wrapper.
Another way of saying it is that the wrapper is the bootstrap for the presentation layer. Here’s an example wrapper that can be used as a starting point.
It’s a pretty good assumption that every application you create will at least start with a structure like so:
<?php /* application/views/layouts/wrapper.phtml */ ?>
<?php /* @var $this Zend_View */ ?>
<?php echo $this->doctype()."\n"; ?>
<html>
<head>
<?php echo $this->headTitle(); ?>
<?php echo $this->headMeta(); ?>
<?php echo $this->headLink(); ?>
<?php echo $this->headStyle(); ?>
</head>
<body>
<?php /* NESTED LAYOUT SUPPORT */ ?>
<?php if($this->layout()->nestedLayout): ?>
<?php $this->layout()->setLayout($this->layout()->nestedLayout); ?>
<?php else: ?>
<?php $this->layout()->setLayout('default'); ?>
<?php endif;?>
<?php echo $this->layout()->render(); ?>
<?php /* OUTPUT JAVASCRIPT */ ?>
<?php echo $this->headScript(); ?>
<?php echo $this->inlineScript(); ?>
</body>
</html>
From here you should extend your wrapper to add global layout configuration for your app. By extending, I simply mean adding
code directly to the wrapper in order to provide more functionality. Here are a few things that you might be done in your wrapper:
- Setting the doctype and charset
- Setting a base site title that will be appended to downstream
- Linking in CSS libraries like reset, grid system, font-stacks, etc…
- Attaching JavaScript libraries like JQuery, Dojo, YUI, etc…
Inserting site tracking urchins
Note that you should only ever need 1 wrapper in your application, needing more could be a symptom of poor design.
Comment below if you find yourself in a jam.
Step 2 – The Nested Layout
If the wrapper is the bootstrap to our presentation layer, then a nested layout is the layout to our presentation layer.
A nested layout is also just a regular Zend_View script that will be consumed by the wrapper we just created.
It contains markup that is specific to your application. These blocks usually include the header and footer,
and possibly different columns with placeholders for capture. Our wrapper looks for a layout called default.
For the sake of the example we’re keeping it simple:
<?php /* application/views/layouts/default.phtml */ ?>
<div class="container">
<?php /* @var $this Zend_View */ ?>
<div class="header">
<h1>My Application</h1>
</div>
<div class="body">
<?php echo $this->layout()->content; ?>
</div>
<div class="footer">
<p>Copyright 2011</p>
</div>
</div>
Step 3 – The View
At this stage you simple allow Zend Framework to serve the view intended. You’re done.
It’s a surprisingly simple solution that should prove to be worth the time taken to put in place.
Interchanging Nested Layouts
Further along your development you may find a need to switch out the layout for different reasons.
Here are a couple ways to modify which nested layout will be used.
Changing the Nested Layout from a View
The default nested layout will more than likely be the layout you use for most pages, but in the case
that you need a different layout – specifying one is easy. A common use case for this is switching to
a modal layout, a centered window for less content. A good example is a login page:
<?php /* @var $this Zend_View */ ?>
<?php $this->layout()->nestedLayout = 'modal'; ?>
<?php $this->headTitle()->append = 'Login'; ?>
<h1>Please Login</h1>
<?php echo $this->form; ?>
This will tell the wrapper that you want to use the layout application/views/layouts/modal.phtml instead
of the default.
A Nested Layout Per Module
Another common scenario in Zend Framework is the use case of having a layout defined for each module – admin,
www, editor, what have you. This is a slightly more advanced problem that can be solved using a Front Controller
Plugin. Start by registering our soon-to-be plugin:
; application/configs/application.ini
resources.frontController.plugins.nl = Application_Plugin_NestedLayoutPerModule
Now define a plugin that sets the nested layout to the module’s name
/* application/plugins/NestedLayoutPerModule.php */
Application_Plugin_NestedLayoutPerModule
extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$module = $request->getModuleName();
$front = Zend_Controller_Front::getInstance();
$layout = $front->getParam('bootstrap')->getResource('layout');
$layoutDir = $front->getModuleDirectory() . '/views/layouts';
$layout->setScriptPath($layoutDir);
}
}
If you were accessing an admin module via the uri /admin, then the plugin would look for a file called
application/modules/admin/views/layouts/default.phtml.
Variations – Nesting Nested Layouts
Once your nested layouts become fairly advanced, you might find it useful to create specialization yet again. Say,
for example, up until now your main nested layout has a big fat 1 column layout. It’s served you well up until
this point. Now you have a need to add a 2 and 3 column layout. You can create a new nested layout of course, but
then you would have to recreate your extensive header and footer markup you crafted so carefully. You could move
the header and footer to partials and pull them in in both nested layouts – but that requires an uneccessary contract.
Instead, lets create another layout layer, a variation. To use variations, follow the same pattern as nested layouts.
Replace echo $this->layout()->content with the following to allow your nested layout to look for the
presense of a variation layout:
<?php /* application/views/layouts/default.phtml */ ?<
<?php /* @var $this Zend_View */ ?>
<div class="container">
<div class="header">
<h1>My Application</h1>
</div>
<div class="body">
<?php /* VARIATIONS SUPPORT */ ?>
<?php if($this->layout()->variation): ?>
<?php $this->layout()->setLayout($this->layout()->variation); ?>
<?php echo $this->layout()->render(); ?>
<?php else: ?>
<?php echo $this->layout()->content; ?>
<?php endif;?>
</div>
<div class="footer">
<p>Copyright 2011</p>
</div>
</div>
Now lets create a 2 column variation for our default nested layout:
<?php /* application/views/layouts/variations/default-2col.phtml */ ?>
<?php /* @var $this Zend_View */ ?>
<div class="main">
<?php echo $this->layout()->content; ?>
</div>
<div class="sidebar">
<?php echo $this->placeholder('sidebar'); ?>
</div>
<footer>
<p>Copyright 2011</p>
</footer>
Finally, from our login page, let’s take advantage of our new variation:
<?php /* @var $this Zend_View */ ?>
<?php $this->layout()->variation = 'default-2col'; ?>
<?php $this->headTitle()->append = 'Login'; ?>
<h1>Please Login</h1>
<?php echo $this->form; ?>
<?php $this->placeholder('sidebar')->captureStart(); ?>
<p>Forgot your password? That's unfortunate.</p>
<?php $this->placeholder('sidebar')->captureEnd(); ?>
Zend_View is very flexible
Zend Framework makes it easy to create more advanced view layers like this. It’s sometimes useful
to have a peep at how other framework’s addressing this problem, too. Symfony2, for example, uses a
templating language called Twig which makes it easy to implement this
pattern. They’ve detailed their approach in their section on
Three-level Inheritance. It’s
impressive that Zend Framework, who supplies no templating language by default (other than PHP itself), allows
for such crisp plain ‘ol PHP view implementations.