ZF-6865: Zend_Navigation view helper support for multiple instances

Issue Type: Bug Created: 2009-05-30T07:29:09.000+0000 Last Updated: 2010-05-11T15:16:27.000+0000 Status: Resolved Fix version(s): Reporter: Mina R Waheeb (syncer) Assignee: Robin Skoglund (robinsk) Tags: - Zend_Navigation

Related issues: Attachments:


Current implementation of Zend_Navigation view helper only support to handle one instance of Zend_Navigation. Its should serve multiple of navigation instances, similar to placeholder concept. most of the websites contains more than one navigation.

lets say

<pre class="highlight"> 
$main = new Zend_Navigation();
$sidebar = new Zend_Navigation();
$view->navigation($main);  // sets the default
$view->navigation("sidebar", $sidebar); //sets the sidebar view
//etc .. for footer, rightclick menu :)
//easy after that access the navigation in the view
$this->navigation("sidebar") ; //access the side bar navigation
$this->navigation(); // access the default navigation



Posted by Robin Skoglund (robinsk) on 2009-06-13T04:42:39.000+0000

This sounds interesting. Does anyone else have any comments?

What you're requesting needs modifications in the proxy helper that might not be backwards compatible. By the way, is this feature intended for all helpers, or just the proxy helper?

Posted by Mina R Waheeb (syncer) on 2009-06-13T10:50:06.000+0000

We can achieve this with backwards compatible by change the type check in the proxy view helper method signature like the below prototype

<pre class="highlight">
public function navigation(Zend_Navigation_Container $container = null)
// to
public function navigation($container = null, Zend_Navigation_Container $nav = null)
// and add new array to navigation proxy view helper $containers
// if $nav is null then 
//    if $container is a string then call setContainer(containers[$container])
//    if $container is Zend_Navigation_Container then call  setContainer($container)
// else
//    $container must be string then store $nav in the $containers array 
//    then call setContainer(containers[$container])

I believe by this way there is no need to change all the helpers because the mechanism to change the container already exist.

Posted by John John (chetzoff) on 2009-06-14T08:42:42.000+0000

Because of the mentioned problem, at the moment I have to refuse to use this component, because on my site I have 3 menus with different content. Hope that this issue will be resolved as fast as possible in the next version.

Posted by Mina R Waheeb (syncer) on 2009-06-14T09:24:40.000+0000

more readable prototype \

<pre class="highlight">
public function navigation($container = 'default', Zend_Navigation_Container $navigation = null) {
    if($navigation != null) {
         $this->_containers[$container] = $navigation;
    } elseif ($container instanceof Zend_Navigation_Container) {
         $this->_containers['default'] = $navigation = $container;
    } elseif (isset($this->_containers[$container])) {
         $navigation = $this->_containers[$container];
    } elseif($container == 'default') {
         // Maybe better modify getContainer to getContainer($id = null)
         // to allow multi-navs to be stored in Zend_Registry by resources etc...
         // Keys for example: Zend_Navigation_Default, Zend_Navigation_Sidebar, Zend_Navigation_Footer ..
         $this->_containers[$container] = $navigation = $this->getContainer();
    } else {
         $this->_containers[$container] = $navigation = new Zend_Navigation();
    if (null !== $navigation) {
    return $this;

Posted by Mina R Waheeb (syncer) on 2009-07-04T10:02:43.000+0000

any news?

Posted by Ashley Simons (ashleysimons) on 2009-08-04T06:39:33.000+0000

I quickly tried creating a custom view helper that extends the pre built view helper (merely calling the navigation method from my custom view helper's appropriate method) to no avail.

So when I have some time I'll look into both the view helper and zend_navigation to see what methods I'll need to override. However with this line of thought, its hard to be confident about the future compatibility side of things.

I need multiple instances of zend_navigation, per page on my multiple module project.

Posted by Thomas Szteliga (websafe) on 2009-08-24T06:07:34.000+0000

I would like to see this resolved, because i think it is natural to use Zend_Navigation for site's main navigation and a separate instance of Zend_Navigation for a language selection menu or any other kind of "menu" not directly related to site's main navigation.

Posted by Robin Skoglund (robinsk) on 2009-08-24T06:17:56.000+0000

I have not put any work/thoughts into this issue since my last comment. I'm still awaiting more community feedback on possible solutions and requirements.

To be honest, this is not exactly a major issue/drawback with the view helper. You can always store as many container instances you like, e.g. in a registry, and simply render menus for those separately.


<pre class="highlight">
$topNav = Zend_Registry::get('myTopNav');
$sideNav = Zend_Registry::get('mySideNav');
echo $this->navigation()->menu()->renderMenu($topNav);
echo $this->navigation()->menu()->renderMenu($sideNav);

If you want to take it further, you could store the containers in the proxy helper dynamically, and simply do:

<pre class="highlight">
$proxy = $this->navigation();
echo $proxy->menu($proxy->topNav);
echo $proxy->menu($proxy->sideNav);

Posted by Troy Marker (tlmarker) on 2009-09-15T20:36:08.000+0000

I have been trying to get two menu to render on the same page, but i am haveing many problems. I tried Mr. Skoglung's example from above, but am not able to get it to work. Here is what I am doing. Being both menus will be the same on through the application i am putting this code in the Bootstrap.php file for the application: Zend_Registry::set('utility',$container->findByLabel('Page 1')); Zend_Registry::set('main',$container->findByLabel('Page 2'));

And this code I am putting in the layout script: navigation()->menu()->renderMenu(Zend_Registry::get('utility')); ?> navigation()->menu()->renderMenu(Zend_Registry::get('main')); ?>

The container I am using is something I copied out of the online documentation online. For the sake of completeness, I will post it here: $container = new Zend_Navigation(array( array( 'label' => 'Page 1', 'uri' => 'page-1', 'foo' => 'bar', 'pages' => array( array( 'label' => 'Page 1.1', 'uri' => 'page-1.1', 'foo' => 'bar', ), array( 'label' => 'Page 1.2', 'uri' => 'page-1.2', 'class' => 'my-class', ), array( 'type' => 'uri', 'label' => 'Page 1.3', 'uri' => 'page-1.3', 'action' => 'about' ) ) ), array( 'label' => 'Page 2', 'id' => 'page_2_and_3', 'class' => 'my-class', 'module' => 'page2', 'controller' => 'index', 'action' => 'page1' ), array( 'label' => 'Page 3', 'id' => 'page_2_and_3', 'module' => 'page3', 'controller' => 'index' )));

Onces I have this working, I would like to add ACL to it to display only certain parts of the menu.

The above code render the first menu, but not the second. I am at a loss. I have tryin several thing to no avail. Any help would be greatly apreciated.

Thank you in advance. Troy

Posted by Robin Skoglund (robinsk) on 2009-10-16T15:36:47.000+0000

Closing this issue now to clean up the issue tracker. For general help, consult the mailing lists or IRC.

Posted by Julian Pustkuchen (anybody) on 2009-12-08T11:46:31.000+0000

I would be grateful, if you could add the described possibility.

The current implementation is not really good and seperated menus are used quite often I think.

Posted by Julian Pustkuchen (anybody) on 2009-12-08T11:58:20.000+0000

I'd like to add, that this extension would make sense for example for the use of breadcrumbs.

Now if you have several navigations, only the one added to the view will work for breadcrumbs. That's not really nice...

Posted by Phil Brown (philbrown) on 2009-12-17T21:37:16.000+0000

Robin, regarding your example

<pre class="highlight">
$proxy = $this->navigation();
echo $proxy->menu($proxy->topNav);
echo $proxy->menu($proxy->sideNav);

given the absence of __get and __set magic methods in the proxy helper, I can only assume you're directly assigning new, public properties. Don't you think this is a little hacky (it's one of those PHP "features" I've never been happy with)? Perhaps you could implement the aforementioned magic methods to manipulate a protected $_namedContainers array for named navigation containers.

Posted by Philipp Feigl (pfeigl) on 2010-05-11T15:16:26.000+0000

For anyone else trying to get it accomplished, this seems to be a good way to do it:

<pre class="highlight">

calling render (or even renderMenu) directly with an navigation container does not change the internal navigation object of the view helper and simply renders whatever is provided.

Have you found an issue?

See the Overview section for more details.


© 2006-2021 by Zend by Perforce. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.