Introduction to Zend_Layout (updated for ZF 1.5!)

Tags:

I 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.

Further reading:
View inheritance and “blocks” in Zend_View
How to automatically escape template variables in Zend_View