In a continuation on my last post about Zend_Navigation, Route requests for sitemap.xml to custom controller/action, this post is about dymnamically adding pages to a Zend_Navigation container at runtime/script execution.
Its all well and good specifying your pages in a ini or xml file but at some point you’re going to have changing pages in your site that you want as part of a menu, sitemap, or to be included in your breadcrumb trail. Therefore what we need to do is add pages to our Zend_Navigation container at runtime. Examples for this would be in adding news items, blog posts, or page comments, etc.
In this example I’m going to add some news posts to my statically defined ini config. To get my news post page configurations I’ve used a class which returns an array in the following format:
$pagesToAdd = array ( 0 => array ( 'label' => 'Fake news story #5...', 'module' => 'www', 'route' => 'www-index', 'action' => 'view', 'controller' => 'news', 'params' => array ( 'id' => '5-Fake-news-story--5' ) ), 1 => array ( /* More page details */ ), );
As you’ll notice that the function has returned an array in which are contained arrays which make up the config arrays for Zend_Navigation_Page_Mvc. Therefore, by looping over the array new Zend_Navigation pages can be created from the config array. The next thing to do as part of the loop is to to add the pages in the correct position (alternatively pages can be added in bulk by using ->addPages() method).
To do this, locate the page you wish to add the sub-pages to and simply add the pages. In this case I have used the following code to find my page:
$container->findOneBy('label', 'Latest News')->addPage($page);
My overall navigation initialisation in the bootstrap therefore looks like this:
/** * used for handling top-level navigation * * @return Zend_Navigation */ protected function _initNavigation() { $this->bootstrap('layout'); $layout = $this->getResource('layout'); $view = $layout->getView(); $config = new Zend_Config_Ini( APPLICATION_PATH . '/configs/navigation.ini', APPLICATION_ENV); $container = new Zend_Navigation($config->default); // Now add the last 25 news reports $news = new News(); $pages = $news->getNavigationEntries(); foreach ($pages AS $page) { $page = new Zend_Navigation_Page_Mvc($page); $container->findOneBy('label', 'Latest News')->addPage($page); } $view->navigation($container); }
On thing that needs to be added is some form of caching (using Zend_Cache presumably ;)) otherwise this is going to be quite expensive with each page load.