How To Implement Partials In Zend Framework 1.0.3

February 11th, 2008

The pre release of Zend Framework 1.5 has been out for a few days and includes an implementation for partials – among other things. But the GA release is still at least a few weeks off and I’ve got a project that needs to go live very soon. So, I’m using version 1.0.3 of the Zend Framework released on 11/30/2007, and I want to make use of partials in my project. The trick involves three steps.

  1. Create a View Helper
  2. Access your Zend_View object from the View Helper (or instantiate a new one)
  3. Render a view script from within the View Helper

View Helpers

Zend View Helpers were designed to make it easier to render somewhat complicated output that you might need to repeat multiple times throught your application. The Zend Framework comes with a handful of View Helpers for things like rendering form buttons, form fields, urls, and html lists. The Zend Framework Documentation, however, seems to suggest that View Helpers bundle their application logic with their presentation markup. For example, here is the code from the FormText.php view helper that comes with the Zend Framework.

PHP:
  1. public function formText($name, $value = null, $attribs = null)
  2. {
  3.     $info = $this->_getInfo($name, $value, $attribs);
  4.     extract($info); // name, value, attribs, options, listsep, disable
  5.  
  6.     // build the element
  7.     if ($disable) {
  8.         // disabled
  9.         $xhtml = $this->_hidden($name, $value)
  10.                . $this->view->escape($value);
  11.     } else {
  12.         // enabled
  13.         $xhtml = '<input type="text"'
  14.                . ' name="' . $this->view->escape($name) . '"'
  15.                . ' id="' . $this->view->escape($id) . '"'
  16.                . ' value="' . $this->view->escape($value) . '"'
  17.                . $this->_htmlAttribs($attribs)
  18.                . ' />';
  19.     }
  20.  
  21.     return $xhtml;
  22. }

Notice in the else block how the markup is written out and stored in the $xhtml variable. For simple snippets, this is ok but if you have a complex view that you want to work with then you really need to break the presentation markup out of your View Helper and into a View Script.

Access The View From Your ViewRenderer Or Instantiate A New Zend View

The next thing the View Helper needs is a Zend_View object so that it can render the view script that holds the presentation markup. I chose to reuse the globally available Zend_View by accessing it from the ViewRenderer Helper like this.

PHP:
  1. $view = Zend_Controller_Action_HelperBroker::getExistingHelper('viewRenderer')->view;

The benefits of reusing the Zend_View that you already have is that you do not have to worry with setting the basepath or the script path. Also, if you have done any customization of your Zend_View then you have access to the customizations from your View Helper. Note, however, that since you are litterally using the same Zend_View in your View Helper as you are using in your Controllers, you need to be mindful of variable clashes since everything is all in the same namespace. For example, if you set

PHP:
  1. $this->view->someVariable = "some value";

in your controller then you have access to this variable in your View Helper and the view script that your View Helper is rendering.

If you prefer to set up a new namespace for your View Helper and it’s view script, you can instantiate a new Zend_View in your View Helper. This also let’s you set up a different directory for storing the view scripts for your View Helper if you so wish. If you want to create a new Zend_View, you can do it like this.

PHP:
  1. $config = Zend_Registry::get('config');
  2. $view = new Zend_View();
  3. $view->setScriptPath($config->basepath . "app/views/scripts");

Note that I am storing my basepath in a config file for the sake of portability.

Render A View Script From Your View Helper

The last piece of the puzzle is rendering the markup code that we decoupled from the View Helper logic. The presentation markup for the View Helper is stored in a view script – just like the view scripts for your Controller’s actions. I store the view scripts for my partials in applications app/views/scripts/controllerName directory along with all my other view scripts. If you have a lot of view scripts or partials, feel free to store them in their own directory or however you want to organize them.

I am working on a project that manages medical records. I need to display a list of allergies for each patient in my system. I created a partial to which I pass the patient and the type of allergy list to display – drug allergies or other allergies. So, when all the pieces are put together, the code looks like this:

PHP:
  1. /** The View Helper
  2. * file: app/views/helpers/AllergyList.php
  3. */
  4.  
  5. class Zend_View_Helper_AllergyList {
  6.  
  7.   public function allergyList($patient, $allergyType) { 
  8.     $view = Zend_Controller_Action_HelperBroker::getExistingHelper('viewRenderer')->;view;
  9.     $view->patient = $patient;
  10.     $view->allergyType = $allergyType;
  11.     $out = $view->render("vitalkey/prtlAllergy.phtml");
  12.     return $out;
  13.   }
  14. }

PHP:
  1. /** The View Helper's View Script
  2. * file: app/views/scripts/vitalkey/prtlAllergy.phtml
  3. */
  4.  
  5. <?php foreach($this->patient->getAllergies() as $allergy): ?>
  6.   <?php if($allergy->allergy_type == $this->allergyType): ?>
  7.     <h1>
  8.       <?php if(!empty($allergy->diagnosed_on)): ?>
  9.         <span class="diagnosedDate">Diagnosed: <?= date("m/Y", strtotime($allergy->diagnosed_on)) ?></span>
  10.       <?php endif; ?>
  11.       <?= $allergy->name ?>
  12.     </h1>
  13.  
  14.     //... other code to display allergic reaction details

PHP:
  1. /** The View Script for the Controller Action
  2. * file: app/views/scripts/vitalkey/patientData.phtml
  3. */
  4.  
  5. //... Lots of patient data markup
  6.  
  7. <h2>Drug Allergies</h2>
  8. <div class="patientDataBox">
  9.   <?= $this->allergyList($this->patient, "drug"); ?>
  10. </div>
  11.  
  12. <h2>Other Allergies</h2>
  13. <div class="patientDataBox">
  14.   <?= $this->allergyList($this->patient, "other"); ?>
  15. </div>
  16.  
  17. //... Lots more patient data markup

So that is how I handle partials with Zend Framework 1.0.3. Let me know if you have any tips on how to improve any of this. Thanks for reading!mat

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Netvouz
  • DZone
  • ThisNext
  • MisterWong
  • Wists

Leave a Reply