Content with Style

Web Technique

View variables in Zend Framework Partial Loop

by Pascal Opitz on July 30 2008, 10:58

One of the fun things about Zend Framework is the possibility to extend the Framework classes with extras functionality.
I got slightly annoyed that in a partialLoop I couldn’t access the view variables. here’s how I fixed it.

First of all we need to understand that the Helpers get overwritten, if we declare custom ones with the same name.

Therefore, if I create a helper class partialLoop and load it via declaring a helper path, it will overwrite the Zend Framework one.

In my case I just added this into the init function of the Base Controller:


public function init() {
	$this->view->addHelperPath('/path/', 'Extended_Helper');
}

Within the declared path I now have to add a file called PartialLoop.php


<?php

require_once 'Zend/View/Helper/PartialLoop.php';

class Extended_Helper_PartialLoop extends Zend_View_Helper_PartialLoop {

	public $view;

	public function setView($view) {
		$this->view = $view;
		$this->config = Zend_Registry::get('config');
	}

	public function partialLoop($path, $array) {
		return parent::partialLoop($path, $array);
	}


	public function partial($name, $module, $item) {
		$item['view'] = $this->view;
		$item['config'] = $this->config;
		return parent::partial($name, $module, $item);
	}
}

And voila, we now can access the view from within a partialLoop.

Comments

  • I thought the whole point of partial is to make a separate scope for the rendered view. At least I wouldn’t override the default partialLoop with one that doesn’t, since it could break some views if I’m reusing things from elsewhere.

    foreach with $this->render would probably do exactly the same, except allow you to access the variables without any mods.

    by Jani Hartikainen on September 8 2008, 02:22 #

  • Hi Jani,

    of course this is a convinience hack for me, but note that I applied it to partialLoop and not partial. What’s the difference you might ask?

    Well, the way I use partialLoop is mainly for stuff that I get in an array, i.e. DB return values of SOAP stuff. While I can easily build one array for rendering a partial, and pass $view into it for this one specific redendering process, if I did this for every row of the array that I want to reder through partialLoop, I have to iterate through the whole array and do the same, which is annoying.

    I decided to use this hack as my own convention, as I nearly every time found myself in need for stuff that I needed in the view. And $this->view is the only thing I overwrite for it, really. So until you have some DB table that has a ‘view’ field, you’re fine.

    There’s no supersolution here, and like with most stuff: If this doesn’t work for you, then basically don’t use it.
    But even then I think this is a good insight into how you can manipulate Zends built in functionality by extending classes rather than messing about with the core files.

    by Pascal Opitz on September 8 2008, 02:37 #

  • For same reasons as Pascal mentioned, I wanted this feature. Thanks a lot.

    by under on October 3 2009, 10:29 #

  • thank you for this, it helps me a lot!

    by cotoyomi on August 2 2009, 22:55 #

  • Found this thread while I was examining why PartialLoop couldn't access the view. I liked the solution but I did it a bit differently. I Made a new class named differently since if I wanted to use the functionality of the original partial loop I should be able to. Also I made it possible to send an array of objects instead of array. Only downside is the object key is defined as 'object' in the constructor and must therefore be that in the partials too.

    
    class My_View_Helper_ExtendedPartialLoop extends Zend_View_Helper_PartialLoop
    {
    	public $view;
    
    	public function __construct()
    	{
                    // Parent doesn't have a constructor so we don't call it.
    		$this->setObjectKey('object');
    	}
    
    	public function setView(Zend_View_Interface $view)
    	{
    		$this->view = $view;
    	}
    
    	public function ExtendedPartialLoop($path, $array)
    	{
    		return parent::partialLoop($path, $array);
    	}
    
    	public function partial($name, $module, $item)
    	{
    		$objectKey = $this->getObjectKey();
    		if(is_object($item) && isset($objectKey) && $objectKey != 'view')
    		{
    			$item = array($objectKey => $item, 'view' => $this->view);
    		}
    		elseif(is_array($item) && !isset($item['view']))
    		{
    			$item['view'] = $this->view;
    		}
    		else
    		{
                            // Throw whatever exception you use for these cases.
    			throw new ProgrammingError();
    		}
    
    		return parent::partial($name, $module, $item);
    	}
    }
    

    by Borje on March 25 2010, 08:27 #