Introduction to Zend_Layout (updated for ZF 1.5!)
March 17, 2008 – 6:59 pm Tags: Zend FrameworkI wrote earlier a post about the back then new Zend_Layout component in Zend Framework. It’s one of my most popular posts, so I think it’s about time for me to write an updated version which actually works in ZF 1.5’s version of Zend_Layout.
We’ll look into how to get started with Zend_Layout, and we’ll also check out the new view helpers.
Getting started
Zend_Layout is now included with Zend Framework (since 1.5), so you will be able to start using it right away.
Let’s make one assumption before starting: we have defined a constant called APP_PATH, which contains the path to our application’s root directory. So when you see APP_PATH in the code, you’ll know what it means.
First, in our bootstrap, we need to initialize Zend_Layout (ZL from here on):
Zend_Layout::startMvc(array( 'layoutPath' => APP_PATH . '/application/layouts' )); //Let's assign our imaginary base url in the view so we can refer to it: $view = Zend_Layout::getMvcInstance()->getView(); $view->baseUrl = '/baseurl';
The startMvc command registers ZL’s plugins and such and we can use it to define settings, like the layout path. Since we defined that our layouts reside in application/layouts, we need to create that dir if it does not exist. Assigning the base URL is not absolutely necessary, but it can provide useful if you need to refer to files, such as CSS or JavaScript, in your views and we’ll be using it later in this article.
Next, let’s create the default layout:
application/layouts/layout.phtml
<html> <head> <title>Layout example</title> </head> <body> <?= $this->layout()->content; ?> </body> </html>
The above creates a simple HTML page. The PHP code snippet there displays the data rendered in your actions. It is essentially a view script, so you can use view helpers and such in it.
This is all we need. You now have a working Zend_Layout enabled site! Just add controllers and the other usual stuff. By default, Zend_Layout will include the contents rendered by the view in your actions in the content variable shown in the above layout code, so you will not have to do anything special to get your views rendered inside the layout.
Zend_Layout view helpers
There’s a couple of new view helpers that help us with various tasks related to layouts.
The doctype and head helpers
Let’s modify our layout.phtml a bit:
<?= $this->doctype(Zend_View_Helper_Doctype::XHTML1_TRANSITIONAL); ?> <html> <head> <?= $this->headTitle('Layout example'); ?> <?= $this->headLink()->appendStylesheet($this->baseUrl.'/css/example.css'); ?> <?= $this->headScript(); ?> </head> <body> <?= $this->layout()->content; ?> </body> </html>
We can see some helpers in action there. The doctype, headTitle, headLink and headScript helpers.
The doctype helper is used to render the DOCTYPE tag, which is quite nice as I can’t ever remember its syntax! You simply pass one of the constants of Zend_View_Helper_Doctype to it as a parameter.
The head helpers are a bit more advanced. Their job is to render various elements you see in the head tag, such as the title, link elements for CSS and script elements for JavaScript.
Why are they needed instead of just using HTML? For example, if you have a specific action, which requires some JavaScript code. You probably would not want to include the JavaScript code on pages where it is not needed, because it would make your pages bigger and slow down loading etc., so you can simply use the headScript helper:
A view script for myAction in MyController
<?php //Let's add some JS and CSS and change the title: $this->headScript()->appendFile($this->baseUrl . '/js/something.js'); $this->headLink()->appendStylesheet($this->baseUrl . '/css/new.css'); $this->headTitle(' myAction MyController'); ?> <h1>Bla bla</h1> Some HTML etc. here.
Now, the above code would make the layout include a JavaScript file, add another CSS file and modify the title so that in addition to “Layout example”, it says “myAction MyController”.
The partial and partialLoop helpers
partial and partialLoop can be used to render sub-views, in the same way as you would use $this->render(…) in a view script to render another view script inside it. The main difference between using render() and partials is that partials are rendered in a separate scope, meaning that you will not be able to access the view variables in the parent view from inside your partial views.
When using partials, you’ll need to pass the viariables to it:
<?= $this->partial('mypartial.phtml', array('var1' => 'hello', 'var2' => 'world')); ?>
The above would render mypartial.phtml, and assign two variables in it: var1 and var2.
Partialloop is basically the same, except it can be used to render the same partial multiple times, like the name says.
The action helper
The action helper is used to call actions from inside the views. This can be useful for various things, such as rendering content which needs to be loaded from the database, but isn’t necessarily related to the current “main” action.
Let’s modify our layout.phtml again:
<?= $this->doctype(Zend_View_Helper_Doctype::XHTML1_TRANSITIONAL); ?> <html> <head> <?= $this->headTitle('Layout example'); ?> <?= $this->headLink()->appendStylesheet($this->baseUrl.'/css/example.css'); ?> <?= $this->headScript(); ?> </head> <body> <div> <?= $this->action('menu', 'layout', 'default'); ?> </div> <?= $this->layout()->content; ?> </body> </html>
So we added a call to $this->action in the layout. It will call LayoutController’s menuAction method, in the default module. The syntax used for the parameters is the same as for _forward(), so you can also pass parameters to the action:
$this->action('action', 'controller', 'module', array('param1' => 'foo', 'param2' => 'bar'));
You can call any actions you want with the action helper. It will call it and get the rendered view and output it on the page. Note that plugins (such as Acl) will not be applied!
In closing
Now you should know enough to get going with Zend_Layout. Feel free to ask any Zend_Layout related questions in the comments!
Don’t forget to see the Zend_Layout documentation and the documentation for view helpers, as they contain more useful information you may need at some point.

15 Responses to “Introduction to Zend_Layout (updated for ZF 1.5!)”
I’d recommend calling the doctype() helper with the doctype you want from your bootstrap. The rationale is that a number of the view helpers are doctype aware — such as the form*() helpers — and defining the doctype early allows these to render correctly for the doctype you desire. Then, in your layout, you only need to call $this->doctype() to render it.
By Matthew Weier O'Phinney on Mar 17, 2008
That’s a good tip. Wouldn’t have thought about that myself.
By Jani Hartikainen on Mar 20, 2008
Hi,
Is it possible to render a seperate layout (or a seperate view template) into a variable after its rendered with the smarty class? (with help from your smartyview and smartyviewadvanced class)
By Pluto on Mar 24, 2008
How does one go about setting the layout path when they are using modules? I.E.
modules/
- admin/
—- views/
——-layouts/
- default/
—- views/
——-layouts/
Is there any way to configure Zend so that it includes the correct layout file depending on the module being used.
Zend_Layout::startMvc(array(’layoutPath’ => ‘../application/modules/:module/views/layouts’));
where the :module variable would be the current module in quesiton
By Hayden on Mar 30, 2008
Hayden: the assumption with Zend_Layout is that all layout scripts are kept in a common directory, regardless of module.
That said, it’s trivial to switch the layout directory — and layout script — from a given controller or view script — both action and view helpers exist for the layout object.
You can also easily extend Zend_Layout to add the functionality you desire. If you feel it’s a common enough pattern, please propose it on the mailing lists.
By Matthew Weier O'Phinney on Mar 30, 2008
Hi Matthew,
Nice introduction to Zend_Layout.
A detail that bothers me is that the string from the $this->headTitle() located in the view script is not added at the end of the one from the layout $this->headTitle() but at its beginning… or did I do something wrong??
By A developpeur in Paris on Apr 12, 2008
To the developpeur in Paris:
I noticed that the title is appended as well. To fix that, I did:
headTitle(’Layout example’, ‘PREPEND’); ?>
within layout.phtml
By edtechre on Apr 23, 2008
Hi,
I have this in my bootstrap file:
some code …
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory(array(’default’=>’../application/default/controllers’,'admin’=>’../application/admin/controllers’));
Zend_Layout::startMvc(array(’layoutPath’=>’../application/layouts’));
$frontController->dispatch();
All is good if I access my action script in ‘default’ path, like this http://project/index and index controller with index action is run, but if I try http://project/admin/ I am getting ‘Invalid controller specified (index)’ because it still looks into ‘defaul’ path for admin controller… Is anybody knows how to access ‘admin’ controllers?
My layout:
/aplication
admin/
controllers/
views/
scripts/
same for ‘default’
layouts/
models/
/lib
/public
Any help please?
Thanks
Alex
By alex on May 1, 2008
Alex,
Try using $frontController->setModuleDirectory(’../application/modules’) and put your admin/ and default/ dirs under there. I’d say that is a better approach, as you won’t have to edit the bootstrap every time you add a new module.
By Jani Hartikainen on May 1, 2008
Hi,
Now I am getting this:
‘Zend_Controller_Exception’ with message ‘No default module defined for this application’
I have this lines in bootstrap (index.php)
$frontController->setModuleControllerDirectoryName(’../application/modules’);
$frontController->setDefaultModule(’default’);
The $frontController->setModuleDirectory(’../application/modules’)
gives error - undefined property setModuleDirectory
Can you please help, I am beginner with ZF
Thanks
Alex
By alex on May 2, 2008
Yeah the correct method would be addModuleDirectory, not setModuleDirectory. I just remembered it wrong. =)
Anyways, I would suggest you check out the ZF manual ’cause it’s said there too, and you might get an answer faster that way.
By Jani Hartikainen on May 2, 2008
Hi,
I have found the answer to my question. The set-up is working, problem was in naming objects (classes). For example: if you have controller in admin/controllers module, you still need to create ActionController.php BUT your class name must be prefixed like this admin_ActionController, other wise Zend won’t find it. I hope this will help somebody else as well.
Thanks
Alex
By alex on May 6, 2008