View Helpers in Zend Framework

Views in MVC are allowed to communicate with the Model (using read-only
operations), and are allowed to perform display-related logic. That said,
how do you actually access the model? And what if you have some fairly
complex logic that you may need to repeat, or which you may not want to
display directly in the view in order to keep it clean and easy to read?
In Zend Framework, the answer is to use View Helpers.

What is a View Helper?

A View Helper is simply a class that follows particular naming conventions,
When attached to a view object, you can call the helper as if it were a
method of the view object itself. The View object retains helper instances,
which means that they retain states between calls.

Common use cases for view helpers include:

  • Accessing models
  • Performing complex or repeatable display logic
  • Manipulating and formatting model data
  • Persisting data between view scripts

Creating and Registering a View Helper

The naming conventions are simple. The class must end with the name of the
helper in MixedCase, and contain a method named after the helper using
camelCase. As an example, if we had a helper named ‘FooBar’, we’d need a
class that ended in ‘FooBar’ with a method named ‘fooBar’. View Helper
classes need a class prefix as well; they can’t just be named after
themselves (more on this later). We’ll give our helper the prefix
‘My_Helper’, and it might look like this:

Following the ZF coding standards, let’s save that in our library as
My/Helper/FooBar.php.

Now we need to register the view helper with the view object.
Zend_View doesn’t allow you to register individual helpers with
it, but you can specify paths to helpers. We’ll do this by calling
the addHelperPath() method, which takes the arguments
$path and $prefix:

You can now call this helper as if it were the fooBar() method
of the view object:

Now, what if you need access to the view or other helpers from
within your helper? If you specify a setView() method
in your helper, Zend_View will then inject the current view
object into the helper after instantiating it. Let’s modify our helper to
add this functionality:

Now it’s time to ask yourself what the helper should return.
By convention, your helpers should never actually echo any content; they
should return it. Most helpers will do precisely that — returning content.
However, a number of helpers will return instances of themselves — which
allows you to then call additional methods on the helper class. This is
potentially useful when you need to be able to provide state information, or
have a group of related functionality but don’t need or want multiple
helpers to accomplish it. Finally, you may opt to return nothing, and
instead simply perform an operation; one example might be logging page
requests.

In our example, we’ll modify the helper to accept a “name” argument, and
then simply return the string ‘fooBar ‘ plus the name; we’ll escape the name
using the view object’s escaping mechansims. Not terribly helpful, but it
helps illustrate the concept:

Factoids on Helper Paths

Now, a few notes on helper paths and prefixes. First, the path and class
prefix need not have a one-to-one relationship as might your other library
code; what is important, however, is that all classes in that
directory have that class prefix. Zend_View will merely check
to see if a class file with the helper name exists in that directory, and,
if not, move to the next directory in the stack. This means you can group
your helpers in one or more directories, then register these paths with the
view object once — and have access to all helpers in those paths.

Second, we mentioned earlier that you need class prefixes. The reason is to
prevent collisions between libraries and standard class names. This also
allows you to extend existing helpers to provide additional functionality
(e.g., the partialLoop() helper extends partial()).

Third, building on this last point, helper paths, as is the case with all
plugin paths in ZF, operate as LIFO stacks. This allows
you to create helpers with your own class prefix and have them override
helpers of the same name with different prefixes. In other words, it allows
you to override the behavior of the standard helpers shipped with ZF.

Building on this last point, let’s say you don’t like how the
formHidden() view helper works; you want it to include an extra
class always — so that you can easily pull all hidden elements
using javascript to perform an operation on them. Overall, the base
functionality is fine, so you might do something like this:

You could then add a path to this helper to your view object:

and then, any time formHidden() is called, your new helper will
be called.

In summary, helpers are a great way to extend the functionality of
Zend_View — and also a great way to customize and extend other
helpers themselves!

Standard View Helpers

So, now that we’ve covered how to create view helpers and register them with
the view object, you might be wondering what view helpers are available. The
answer is, actually, quite a few.

The standard view helpers shipped with ZF 1.5 fall into roughly three
categories: form helpers, placeholders, and utility helpers:

Form Helpers Placeholders Utility
fieldset()
form()
formButton()
formCheckbox()
formErrors()
formFile()
formHidden()
formImage()
formLabel()
formMultiCheckbox()
formNote()
formPassword()
formRadio()
formReset()
formSelect()
formSubmit()
formText()
formTextarea()
htmlList()
placeholder()
doctype()
headLink()
headMeta()
headScript()
headStyle()
headTitle()
inlineScript()
action()
declareVars()
json()
layout()
partial()
partialLoop()
translate()
url()

I won’t go into what each does; most are self-explanatory, and all
are documented in the manual
. However, several of these are worth
mentioning specifically.

Partials

Zend_View has the method render(), which allows
you to render a view script. However, every successive view script rendered
by the view object will have the entire variable scope of the script
preceding it. This can lead to some awkward issues when you want to re-use a
script over multiple iterations, or when you want to manipulate view
variables (which could have consequences for later scripts).

Enter partials. The big difference between rendering a partial and
a normal view script is that a partial gets its own variable scope; it will
only see the variables passed to it directly. As an example, take the
following call to a partial:

Were we to call the foo.phtml script normally, it would inherit
all variables in the view. However, calling it as a partial, as above, it
now only receives a single variable, ‘foo’, with the value ‘bar’.

Where might this be useful? One particular case is for looping through
result sets from your model. In fact, this case is so common that an
additional, slightly more performant, helper was created,
partialLoop(). This helper allows you to pass a result set,
over which the helper than iterates, passing the individual result to the
specified partial.

Let’s say we had a Zend_Db_Table_Rowset stored in the
results member of our view. Each item in the rowset is a
Zend_Db_Table_Row; this will be passed to our partial, which
will then be able to use the fields in the row as if they were view
variables. If our table had the fields ‘username’ and ’email’, we could then
create a partial like the following:

Our view script would then call it in the following context:

Partials allow us to operate in a clean scope and separate out useful
tidbits of code for re-use in our applications. Additionally, you end up
with cleaner, more concise application view scripts that contain less
logic and maintain better readability.

Placeholder Helpers

The basic premise around placeholders is persisting content between views.
Within Zend Framework’s MVC, in most cases placeholders do not make sense;
since the same view object is utilized between all controllers and the
layout by default, you can simply utilize view variables as a persistent
storage mechanism. So, why bother with a specific placeholder
implementation?

There are actually several reasons. First off, not everyone uses the same
view object, opting instead to use a separate view object for each discrete
rendering task. Second, and more commonly, developers are using partials —
which have their own variable scope. The only way to persist information
from a view script to a partial will be with a placeholder (or by explicitly
passing the information into the partial). Third, some placeholders are used
to provide defaults and hinting to other helpers — the
doctype() helper is a prime example of this. Finally,
placeholders offer the ability to aggregate and capture content for later
use.

Let’s look at some of these points in more detail.

Doctype

The doctype() helper allows you to specify the HTML DocType for
the final output. This helper is then consulted by many other helpers to
determine how to perform markup; for example, <link> tags do not need
to be closed in HTML4, but in XHTML1, they do. If you wanted to make your
own helper DocType aware, you could then add a check as follows (assuming
you’ve allowed for the view to register itself with the helper):

For this to work, however, you have to tell the doctype helper
what DocType is being used before making such calls; otherwise,
they will use the default (which is HTML4 transitional). Add the following
call to your bootstrap or an early-running plugin:

In your layout, simply echo the doctype:

Capturing Content

Oftentimes, you need to generate content within an application view
to inject elsewhere in the layout. How can you both generate the content
dynamically and push it into a placeholder?

The answer is simple: placeholders support capturing. So, as an example:

You can then echo out the placeholder later, and the values will have been
filled in:

While this is useful in and of itself, it’s even more useful when combined
with the following topic: content aggregation.

Content Aggregation

Placeholders actually use a storage container that extends
ArrayObject. This gives them some incredible features and
offers some flexibility that wouldn’t be possible if they were simply stored
as values.

As an example, let’s say you’re building a sidebar for your site, and it
will consist of one or more blocks of content. The sidebar itself needs to
be wrapped in a particular div element, and expects to have
child div elements contained within it. The actual blocks,
however, are dynamic and will be determined by the current user, the page
they are on, and the section of the site they are in.

Since our placeholders are basically glorified arrays, we can actually
append new values into them easily. This allows us to persist the sidebar
between view scripts and then add to it. Additionally, we’ve built in the
ability to specify content with which to surround and separate the items
aggregated in the placeholder.

Let’s setup the basic sidebar defaults:

What the above does is create a new placeholder, ‘sidebar’. We then set the
text with which to begin the output to be the sidebar div, with a child div
of a sidebar-item. We separate multiple items in the sidebar by closing off
the previous sidebar-item div and starting a new one. Finally, we close the
last child div and the sidebar div.

If you’re a stickler for the presentation of your HTML, you can also
indicate indentation; indentation will be prepended to all items rendered in
the placeholder:

Note: the above settings can be done any time prior to rendering
the placeholder.

Now, let’s say that we want to display a box showing login status; if the
user is logged in, we display their name; if they are not, we display a
login button. We’ll run this from a plugin that runs at
dispatchLoopStartup():

Our application view script might then want to display a set of links. We’ll
utilize capturing to grab these and set them in the sidebar. By default,
capturing appends to the placeholder, which is exactly what we want to do.

In our layout script, we can echo the placeholder:

Which will generate the following output:

What if you want to prepend an item to the placeholder? or set it at a
particular index? No problem — use the prepend() or
offsetSet($index, $content) methods. If you want to limit your
placeholder to a single item of content, use the set() method.

Special Placeholder Implementations

There are a number of placeholder implementations contained in the standard
distribution. All of these have the same base functionality as the standard
placeholder() helper, but also extend it. Primarily these are
used for providing information to the layout script in the form of
aggregated <head> content — the page title, scripts, and stylesheets.

For more information on these, you may want to take a look at the following
resources:

Final Word

View Helpers are at heart fairly simple and trivial to implement and utlize.
However, they can add some extremely rich support for your display layer,
help you keep your view scripts clean and manageable, and isolate and
encapsulate often-used logic — allowing you to adhere to the DRY principle.
If you haven’t been using helpers, or if you’ve only been using a subset of
them, give them a try!

And, in case you missed the previous articles:

About Matthew Weier O'Phinney

Matthew is a Principal Engineer at Zend Technologies. He is currently project lead for both Zend Framework and Apigility; a Zend Certified Engineer; and a member of the Zend Education Advisory Board, the group responsible for authoring the Zend Certification Exam. He contributes to a number of open source projects, blogs on PHP-related topics, and presents talks and tutorials related to PHP development and the projects to which he contributes. You can read more of his thoughts on his blog, mwop.net/blog.