Implementing a menu with Zend_Navigation

A few weeks ago I saw a very good ZendCast about Zend_Navigation.

This was a very good start for me to use Zend_Navigation for the menu and breadcrumbs in my application.

Performance

While developing there were some performance issues that came up:

  1. parsing a .ini or .xml file makes the application slower
  2. for Ajax-requests, the menu should not be loaded

The solution for the first problem is a simple array. I created a function getMenu() that returns a Zend_Navigation object, and this object contains my menu array. The array is less readable than a .ini or .xml file, I have to admit, but it’s still very easy to work with.

private function getMenu()
{
    return new Zend_Navigation(array(
        array(
            'label' => 'Home',
            'id' => 'home',
            'visible' => false,
            'controller' => 'index',
            'action' => 'index'
        ),
        array(
            'label' => 'Page 1',
            'id' => 'page_1',
            'uri' => '',
            'pages' => array(
                array(
                    'label' => 'Page 1.1',
                    'id' => 'page_1_1',
                    'controller' => 'general',
                    'action' => 'index'
                )
            )
        )
    ));
}

For the second problem I had to dig a little bit deeper into Zend Framework.
Normally the Zend_Layout and Zend_View are created in the bootstrap. And this is also the place where I would initialize Zend_Navigation.
For an Ajax request, I disable the layout.

$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender();

Does it make sense to first create the layout and view, then add the menu to the view, and afterwards disable the layout if the application do an Ajax request?

My solution was this: I created a plugin for the menu. This plugin checks if the layout is enabled or disabled, and only creates the menu when the layout is enabled. The plugin uses the postDispatch method, because only then the layout can be checked if it is enabled or disabled. In the preDispatch it is always enabled.

public function postDispatch(Zend_Controller_Request_Abstract $request)
{
    $layout = Zend_Layout::getMVCInstance();
    $view = $layout->getView();
 
    if ($layout->isEnabled() && Zend_Auth::getInstance()>hasIdentity()) {
        $view->navigation($this->getMenu());
    }
}

Difference between URI and MVC

This is a very simple difference.

Zend_Navigation_Page_Mvc uses the parameters “controller” and “action” to create the anchors in the menu.
Zend_Navigation_Page_Uri uses the “uri” parameter the create the anchor.

I use only Mvc to create my anchors.
I use the Uri for one case: if I want a menu item that has no anchor. If the “uri” parameter is left blank, Zend_Navigation will display the label, but it will not create anchor tags around it, so you can create a nice menu with menu titles that are not linkable, and menu items with links underneath

1 thought on “Implementing a menu with Zend_Navigation”

Comments are closed.