Zend Menu extend

654 Views Asked by At

I'm working on a website with a "normal" menu and a submenu.

This is the method in the bootstrap which is resonsible for the navigation:

Bootstrap.php

protected function _initNavigation()
{        
    $view = $this->getResource('view');

    $view->addHelperPath(APPLICATION_ROOT . '/library/Pcw/View/Helper/Navigation', 'Pcw_View_Helper_');          

    $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav');

    $navigation = new Zend_Navigation($config);

    $view->navigation($navigation);

    $menuPartial = array('menu.phtml', 'default');        
    $view->navigation()->menu()->setPartial($menuPartial);

    $subMenuPartial = array('submenu.phtml', 'default');        
    $view->navigation()->subMenu()->setPartial($subMenuPartial);
} 

library/Pcw/View/Helper/Navigation/SubMenu.php

class Pcw_View_Helper_Navigation_SubMenu extends Zend_View_Helper_Navigation_Menu
{
    public function subMenu(Zend_Navigation_Container $container = null)
    {
        return parent::menu($container);
    }
}

According to the docs and topics here on Stackoverflow this construction should work, but the following error comes up:

Fatal error:  Uncaught exception 'Zend_Navigation_Exception' with message 'Bad method call: Unknown method Zend_Navigation::subMenu' in /home/prj/domains/prjon.nl/library/Zend/Navigation/Container.php:366
Stack trace:
#0 [internal function]: Zend_Navigation_Container->__call('subMenu', Array)
#1 [internal function]: Zend_Navigation->subMenu()
#2 /home/prj/domains/prjon.nl/library/Zend/View/Helper/Navigation/HelperAbstract.php(503): call_user_func_array(Array, Array)
#3 /home/prj/domains/prjon.nl/library/Zend/View/Helper/Navigation.php(132): Zend_View_Helper_Navigation_HelperAbstract->__call('subMenu', Array)
#4 /home/prj/domains/prjon.nl/Application/Bootstrap.php(410): Zend_View_Helper_Navigation->__call('subMenu', Array)
#5 /home/prj/domains/prjon.nl/Application/Bootstrap.php(410): Zend_View_Helper_Navigation->subMenu()
#6 /home/prj/domains/prjon.nl/library/Zend/Application/Bootstrap/BootstrapAbstract.php(669): Bootstrap->_initNavigation() in /home/prj/domains/prjon.nl/library/Zend/Navigation/Container.php on line 366

The error is clear: the method subMenu cannot be found and called, but I've created the helper which is responsible for the handling of the submenu..

Does anyone know what I'm doing wrong?

Thanks in advance!

3

There are 3 best solutions below

0
On BEST ANSWER

My code in the plugin file(ROOT/Application/SubmenuPlugin.php):

$view = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('view');

$submenuPartial = array('submenus/'.$currentControllerName.'.phtml', 'default'); //$currentControllerName defined a couple of lines ago             

$view->addHelperPath(APPLICATION_ROOT . '/library/Pcw/View/Helper', 'Pcw_View_Helper_');
$view->navigation()->submenu()->setPartial($submenuPartial);

Location submenus: ROOT/Application/views/scripts/submenus/

Location submenu view helper: ROOT/library/Pcw/View/helper/Submenu.php

Did this help you out?

1
On

I just use a different path syntax and it works for my view helpers, the addHelper() should work with navigation helpers.

$view->addHelperPath(APPLICATION_ROOT . '/library/Pcw/View/Helper/Navigation', 'Pcw_View_Helper_'); 

change to:

$view->addHelperPath('/../library/Pcw/View/Helper/Navigation', 'Pcw_View_Helper_');

works for me, hopefully will work for you as well.

1
On

This is the way I do it, hope it makes sense. I leave out the ACL & Auth integration (which is a great feature).

Lets say I want a top menu with "home" and "admin", and a sub-menu in the "admin" section.

In my Bootstrap :

protected function _initNavigation()
{
    $container = new Zend_Navigation();

    // or in xml etc
    $pages = array(
                array('label' => 'Home', 'controller' => 'index', 'action' => 'index'),
                array('label' => "Admin", 'controller' => 'admin', 'id' => 'admin', 'pages' => array(
                        array('label' => "Add an account", 'controller' => 'admin', 'action' => 'createuser'),
                        array('label' => "Clear cache", 'controller' => 'admin', 'action' => 'clearcache')
                        )
                )
    );

    $container->addPages($pages);

    Zend_Registry::set('Zend_Navigation', $container);
    return $container;
}

Then in my layout I display the main menu :

$container = Zend_Registry::get('Zend_Navigation');
$this->navigation()->menu()->renderMenu($container,array('minDepth' => 0, 'maxDepth' => 0))

(Check the doc for all renderMenu options, very flexible. You can easily make a rollover with the admin sub-menu with 'maxDepth' => 1)

Then in my admin template, to display the sub-menu :

$container = Zend_Registry::get('Zend_Navigation');
$found = $container->findById('admin');
echo $this->navigation()->menu()->renderMenu($found,array('minDepth' => 0))

That way the view rendering is decoupled from the bootstrap, and I don't need partials or custom view helpers.