Zend Layout
Zend_Layout is the Zend Framework implementation of the composite view design pattern. It allows us to display default content for specific parts of a page (Menu, header, etc), and be able to display specific content for the current action.
In this article we assume the use of Zend_Application, we can check Using Zend_Application for bootstraping if necessary.
To start using Zend_Layout you have to add a line to the application.ini specifying the path of your layouts folder and another line to create a view resource. It should look something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[production]
; Error reporting
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
; Paths
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
; ------------- Layouts path
resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"
; ------------- Empty view resource
resources.view[] =
[development : production]
; Error reporting
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
[test : development]
We will also want to modify our Bootstrap class to initialize our view:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initViewResource()
{
// Initialize view
$this->bootstrap('view');
$view = $this->getResource('view');
// Set the doctype to XHTML1
$this->view->doctype('XHTML1_STRICT');
}
}
This is all the configuration we need for our layout to work. By default Zend will look for a file named layout.phtml in our layouts path, so we will need to create it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
// This will print the correct doctype string for the type we chose in
// our bootstrap class
echo $this->doctype().PHP_EOL;
// This stylesheet will be added on the headLink() call below
$this->headLink()->appendStylesheet('/styles/main.css');
?>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<?php
// These view helpers will print the correct tags for meta data, title,
// links (css) and scripts respectively
echo $this->headTitle().PHP_EOL;
echo $this->headMeta().PHP_EOL;
echo $this->headLink().PHP_EOL;
echo $this->headScript().PHP_EOL;
?>
</head>
<body>
<?php
// Will render application/views/scripts/header.phtml
echo $this->render("header.phtml");
?>
<div id="container">
<?php
// Will render the content of the current action.
// The content of the application/views/scripts/index/index.phtml for your
// default action
echo $this->layout()->content
?>
</div>
<?php
// Will render application/views/scripts/footer.phtml
echo $this->render("footer.phtml");
?>
</body>
</html>
This layout includes content from two static files header.phtml and footer.phtml as well as the content for your current action. We will keep our header and footer simple for now:
1
2
3
4
<!-- header.phtml -->
<div>
I am the header
</div>
1
2
3
4
<!-- footer.phtml -->
<div>
I am the footer
</div>
This is how our default controller could add content to the header of the layout:
1
2
3
4
5
6
7
8
<?php
$this->headTitle('Title for this action');
$this->headMeta()->appendName('keywords', 'keywords, for, this, action');
$this->headMeta()->appendName('description', 'Description of the action');
$this->headLink()->appendStylesheet('/styles/controller_sheet.css');
$this->headScript()->appendFile('/js/controller_script.js');
?>
<h1>My title</h1>
At this step we can run our application and we will get this page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Title for this action</title>
<meta name="keywords" content="keywords, for, this, action" />
<meta name="description" content="Description of the action" />
<link href="/styles/controller_sheet.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/styles/main.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/controller_script.js"></script>
</head>
<body>
<!-- header.phtml -->
<div>
I am the header
</div>
<div id="container">
<h1>My title</h1>
</div>
<!-- footer.phtml -->
<div>
I am the footer
</div>
</body>
</html>
Switching layouts
There will be some occasions where we will want to use a layout different from the main one. When this case arrives we can use setLayout() to choose a different one. Here is an example of how a controller can choose a different layout.
application/views/layouts/different_layout.phtml
1
2
3
4
5
6
7
8
9
10
<?php
echo $this->doctype().PHP_EOL;
?>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<body>
<?php
echo $this->layout()->content
?>
</body>
</html>
application/views/scripts/example/index.phtml
1
2
3
4
<?php
$this->layout()->setLayout('different_layout');
?>
I'm an example
This will give as a result:
1
2
3
4
5
6
7
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<body>
I'm an example
</body>
</html>
Creating custom view helpers
Writing our own view helpers is a simple task, but we have to follow some rules so they can play along nicely with Zend Framework:
– We must extend Zend_View_Helper_Abstract when creating our helpers
– The name of the class must start with the prefix specified on our configuration
– The name of the class must end with the helper name, using MixedCaps
– The class must have a public method that matches the helper name, using mixedCaps. This method is the one that will be called when your application calls your helper
– The class should not echo or print or otherwise generate output, instead, it should return values
– The returned values should be escaped appropriately
– The class must be in a file named after the helper class in the format: MixedCaps.php
We will apply all this rules when creating our example view helper, but we need to first tell application.ini where our helpers will live:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[production]
; Error reporting
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
; Paths
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
; Layouts path
resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"
; -------- View helpers path
; -------- My_Application is the prefix we will use in our helpers
resources.view.helperPath.My_Application = APPLICATION_PATH "/views/helpers"
; Empty view resource
resources.view[] =
[development : production]
; Error reporting
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
[test : development]
Following the rules mentioned above we will create a file named HelloWorld.php inside application/views/helpers/:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Class extends Zend_View_Helper_Abstract
// Class name starts with prefix specified in application.ini
// Class name ends with name of the helpers
class My_Application_HelloWorld extends Zend_View_Helper_Abstract
{
// Method with name of the helper in mixedCase
public function helloWorld()
{
// Don't echo
// Return escaped content
return htmlentities('Hello World!');
}
}
Finally we can use our new view helper in any view file as we do with build in helpers:
1
2
3
4
5
<h1>My page</h1>
<?php
echo $this->helloWorld();
echo $this->helloWorld();
?>
php
zend_framework
]