Zend Framework View Helpers


Zend Framework View Helpers allow developers to easily maintain view code, but many existing helpers are coded in very poor form. A few simple guidelines can vastly improve the way developers approach these helpers.

What is a View Helper

A view helper is simply an additional method added to the view object. The Zend Framework includes are number of very simple and easy to use view helpers.

<!-- Inside the View -->
<?= $this->partial('sidebar.phtml'); ?>

This partial view helper does exactly what you would expect it to, it displays the contents of sidebar.phtml onto the page.

Why Use a View Helper

Imagine having to include a bunch of files on a page without using the partial() view helper. The code would get messy pretty quickly since it would be filled with random file opens. The view helper makes it easier since it cuts down on copy-and-paste code and centralizes all logic specific to a certain process in one place. In other words, it keeps code DRY.

All developers have heard of “Fat Model Skinny Controller”, but when it comes to views there is no catch phrase rule of thumb. Many believe that views can be fat (lots of code).  Its perfectly fine for views to contain many lines of code, but high line count in views is often an indicator to add in view helpers.  Think of views in the skinniest way possible by putting every modular part of a page into a custom view helper.

View helpers should exist for any content that could possibly go onto more than one page. For example, a social networking site would have a page that lists all of your friends. The site would also want to display a user’s top ten friends on another page. This is the perfect use a view helper, which we will call friends().

What does a Zend Framework View Helper Look Like?

class My_View_Helper_Friends extends Zend_View_Helper_Abstract {
 
 public function friends() {
  return "hello friends!"
 }
 
}

This is a view helper in its simplest form. Adding this helper to an applicated can be done by calling Zend_View::addHelperPath().

To call this method from a view:

<h1>My Friends</h1>
<?= $this->friends() ?>
<!-- this will output 'hello friends!' -->

Use Chaining

The biggest problem with View Helpers in the Zend Framework Community is that most developers treat them as methods/functions rather than objects. Since they are defined in their own class developers really have no excuse for ignoring the added benefits that come with object oriented programming. Using methods and setters of an class is always going to be more maintainable than passing parameters to a function.

Parameters are messy. The friends helper could take a ton of parameters, such as: The number of friends to display, recent friends, old friends, male friends, female friends, friends in a certain city, it goes on-and-on-and-on. Does this look fun?

<h1>My Female Friends in Boston</h1>
<?= $this->friends(10, 'recent', 'female', $city120) ?>

The function is ugly, it’s impossible to remember the order of parameters, and what happens if another parameter is needed in the function in a few months from now. Refactoring this code is going to be painful.

More important, that function is going to be nearly impossible to unit test. All of the if statements, extra parameters, and default parameters are going to cause nightmares for any coder. The test cases are going to be filled with so much junk in order to test each little section of the function.

This code on the other hand is much easier to read, extremely easy to refactor, and simple to test:

<h1>My Bro Friends</h1>
<?= $this->friends()->show(12)->gender('Male') ?>

Write a render method, Don’t Call it

Its good practice to write a render() method that returns the HTML/final output to the view, but it sure is a pain to have to keep writing “->render()” at the end of each view helper call.

To avoid this use PHP’s magic method __toString().

public function render() {
 return "some html";
}
 
public function __toString() {
 return $this->render();
}

Now every time the helper is called with a short tag it will automatically be displayed.

Things to remember about View Helpers

  1. When chaining an object, the setter methods will have to return instances of the object.
  2. The Zend View object will retain all instances of view helpers. So all default values will have to be reset whenever the helper is called for a 2nd time. See method _defaultValues() below for an example.
  3. The render() method returns HTML/text/output.

Here is what the final friends() helper would look like:

class My_View_Helper_Friends extends Zend_View_Helper_Abstract {
 
 private $_show;
 private $_gender;
 
 public function friends() {
  $this->_defaultValues();
  return $this;
}
 
 private function _defaultValues() {
  $this->show(null);
  $this->gender(null);
 }
 
 public function show($show) {
  $this->show = $show;
  return $this;
 }
 
 public function gender($gender) {
  $this->gender= $gender;
  return $this;
 }
 
 public function render() {
  // .. replace with a method call to gather data based on whats been set
  return "these are my friends: " . $this->_finalOutput;
 }

My Experience

I pretty much put just about everything I can inside a view helper. I have no view that is over 100 lines of code. In fact, most of my pages are just a couple of lines, there are probably very few that contain more than 20 lines. There is a huge benefit here that has nothing to do with DRY principles or the object oriented properties I have mentioned in this article. In fact, it has very little to do with development, but everything to do with team flow:

When a view is skinny and has a majority of its ‘code’ moved into helpers the only thing that remains is text. Views with mostly text allow non technical people to easily edit (and even commit) the pages of your application.

More

Zend Framework View Reference
Devzone Article on Views

From potstuck.com

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s