This tutorial covers a lot of the basic use cases with Zend_Navigation. Using a uri-based navigation.xml file, we generate a very simple menu system as well as a breadcrumb with some basic information. In the last 3 minutes I cover how to get a Google compliant sitemap from the navigation.xml file. This video is by no means exhaustive, but should get you up and running with Zend_Navigation in the Zend Framework.
Browse the code off google code or download a zip here.
On another note, I’m thinking of putting together a forum as a way of organizing some of the informative discussion I’ve found in the comments section. I know other forums exist so I’d be curious to know if you think zendcasts would benefit from such a thing.
Alternatively, if you have topics you’d like covered and are willing to step up to the mic, I’d love to share your own screencasts with the now over 550 subscribers!

That’s <resource>free_account_section<resource>
I have no problem getting the menu to show as you’ve described, but the breadcrumb trail does not show. No errors. Nothing in the source HTML.
Scratching my head and would really appreciate some help debugging this.
Will happily send more details if someone is still responding to this thread
Hi Marc,
We’d like to see more details about your problem.
Regards,
Burn
Burn —
I ultimately was able to sort it out by changing my XML file to use the format:
somecontroller
someaction
For some reason, the /index/about format is a problem.
Probably related to this is that this method:
$uri = $this->_request->getPathInfo();
$activeNav = $this->view->navigation()->findByUri($uri);
$activeNav->active = true;
$activeNav->setClass(“active”);
returns the error:
Call to undefined method stdClass::setClass()
I believe I read somewhere that 1.9 includes setting the ‘active’ class.
So now wondering if this is somehow related to my 1.9 upgrade. Maybe doesn’t support the format?
I can send along the specifics of my bootstrap and ini files, if you think this is something that should still work in 1.9, otherwise I’m happy to plod forward with my new xml.
Thanks much for responding!
Marc
I see my tag signs were mangled…
controller
action
works.
/index/about
didn’t.
Nice to hear it’s already working. I just followed Jon’s video tutorial to the dot:
// controller
$uri = $this->_request->getPathInfo();
$activeNav = $this->view->navigation()->findByUri($uri);
$activeNav->active = true;
// view
$breadcrumbs = $this->navigation() ->breadcrumbs() ->setMinDepth(0)
->setLinkLast(true)
->setSeparator(‘ : ‘);
and yeah, I use 1.9.3.pl.1 and having /user/editprofile causes no problem. May be it got fixed in 1.9.3.pl.1.
Regards,
Burn
I tracked the problem to a simple resource plugin that I was experimenting with a few days ago. Being new to ZF, I’m wondering if you can tell me why it caused a problem:
class Mac_Resource_Plugin_Testview extends Zend_Application_Resource_View
{
public function init()
{
parent::init();
$view = $this->getView();
$view->headTitle()->setSeparator(‘…’);
}
}
I know there is some issue with the view object, but not clear why it conflicts with the navigation scheme.
Hi Marc,
Hmm…. I don’t think headlink has a separator.
That’s headTitle() I’m setting the separator for.
M
hi,
I would like to implment the breadcrumbs. They work except when i have an ID in the URL like
http://www.daily-sudoku.com/dailysudoku/play-sudoku-online/solve-online-207.html
now i do not know how to represent this in the navigation.xml.
any ideas?
Sudoku –
I’m new to the framework but try using this structure for adding parameters to your xml file:
1
2
That didn’t come through. Maybe this will…
<params>
<foo>1</foo>
<bar>2</bar>
</params>
hi,
I can’t use findByUri to achieve the function, do you help me ?
My question write at:
http://www.zendcasts.com/forum/post/284/#p284
please help me, thanks.
hey,
for those of you having problems with empty breadcrumbs and sitemap in zf 1.9.x – just add the following line after creating the Zend_Navigation Object in your Bootstrap.php:
Zend_Registry::set(Zend_Navigation, $yourNavObj);
great tutorial btw
regards from germany
Hi Rock,
You could try and start out with this:
http://framework.zend.com/manual/en/zend.navigation.containers.html
In my site, i.e. footer, I use findByLabel:
$aMenus = array(‘User’, ‘Tools’, ‘Account’, ‘Help’);
for ($i = 0; $i \navigation()-\>findOneByLabel($aMenus[$i]);
…
Regards,
clybs/burn
I have a question though, how do you place a rel=nofollow in the nav xml?
Hey am getting this error
“Uncaught exception ‘Zend_Navigation_Exception’ with message ‘Invalid argument: Unable to determine class to instantiate’ ”
How do i go about it?
What about updating when using ajax calls?
Hi, I don’t think all that stuff in controller init() is necesary since you can drop in your config.xml and use like this:
Logout
default
authentication
logout
Login
default
authentication
login
this way the breadcrumbs automatically know where they are and active pages are automatically assigned. Plus it stays functional even when u change structure of your urls..
For more info: http://framework.zend.com/manual/en/zend.navigation.pages.html#zend.navigation.pages.mvc
P.S.: you can also hide links in menu that aren’t normally available. IE you dont want your guests to see links to the administration area. You will have to have ACL and Auth running which is for another quite HUGE tutorial..
Oops, it deleted all the xml markup… So I’m gonna try again, sorry for double post..
Hi, I don’t think all that stuff in controller init() is necesary since you can drop <uri> in your config.xml and use <module><controller><action> like this:
<?xml version=”1.0″ encoding=”utf-8″?>
<config>
<nav>
<logout>
<label>Logout</label>
<module>default</module>
<controller>authentication</controller>
<action>logout</action>
</logout>
<login>
<label>Login</label>
<module>default</module>
<controller>authentication</controller>
<action>login</action>
</login>
</nav>
<config>
this way the breadcrumbs automatically know where they are and active pages are automatically assigned. Plus it stays functional even when u change structure of your urls..
For more info: http://framework.zend.com/manual/en/zend.navigation.pages.html#zend.navigation.pages.mvc
P.S.: you can also hide links in menu that aren’t normally available. IE you dont want your guests to see links to the administration area. You will have to have ACL and Auth running which is for another quite HUGE tutorial..
How do you get this thing to work, if you use production and development sections in your navigation.xml??
[configdata]
[production]
[nav]
[home]
…
[/home]
[/nav]
[/production]
[development extends="production"]
[/development]
[/configdata]
If i leave the sections out, it complaints it can not find the production section.
If i specify the ‘nav’ section in bootstrap, it complaints it can not find the nav section.
$config = new Zend_Config_Xml(APPLICATION_PATH.’/configs/navigation.xml’, ‘nav’);
Found nothing on the web that relates to this problem, is no one using these build sections???
Very cool dude. Thanks.
Anybody out there who can explain how to integrate Zend-Translate into a menu defined in the navigation.xml?
Is there any way to detect the active menu and add it a class?
Example:
At the homepage have it like:
Homepage
Thanks!
Hi Bruno,
I use something like this:
public function init() {
$this->_locale = Zend_Registry::get(‘Zend_Locale’);
$uri = $this->_request->getPathInfo();
$activeNav = $this->view->navigation()->findByUri($uri);
$activeNav->active = true;
}
Regards,
Burn
It isn’t working, i may be doing something wrong, because i got the following error:
“Fatal error: Uncaught exception ‘Zend_Exception’ with message ‘No entry is registered for key ‘Zend_Locale” in …”
Well, I have multiple menus, so in my bootstrap i got something like this:
$this->bootstrap(‘view’);
$view = $this->getResource(“view”);
$leftmenuConfig = new Zend_Config_Xml(APPLICATION_PATH . ‘/configs/navigation.xml’, ‘leftmenu’);
$leftmenu = new Zend_Navigation($leftmenuConfig);
Zend_Registry::set(‘leftmenu’, $leftmenu);
$rightmenuConfig = new Zend_Config_Xml(APPLICATION_PATH . ‘/configs/navigation.xml’, ‘rightmenu’);
$rightmenu = new Zend_Navigation($rightmenuConfig);
Zend_Registry::set(‘rightmenu’, $rightmenu);
//here i should have something for the menus that i want to specify the active state
$this->_locale = Zend_Registry::get(‘Zend_Locale’);
$uri = $this->_request->getPathInfo();
$activeNav = $this->view->navigation()->findByUri($uri);
$activeNav->active = true;
Can you help me with this?
Thanks,
Hi Bruno,
Try following my setup. In the bootstrap, I have something like this:
protected function _initLocale() {
$locale = new Zend_Locale(‘en_US’);
Zend_Registry::set(‘Zend_Locale’, $locale);
}
protected function _initAcl() {
$this->_acl = new Clybs_Acl();
}
protected function _initNavigation() {
$config = new Zend_Config_Xml(APPLICATION_PATH.’/configs/navigation.xml’, ‘nav’);
$navigation = new Zend_Navigation($config);
$user = new Clybs_User();
$this->_view->navigation($navigation);
$this->_view->navigation()->setAcl($this->_acl)
->setRole($user->getRank());
}
I have ACLs activated for registered users. In your case, you don’t need those I think. Just omit the ones with ACLs.
Regards,
Cliburn M. Solano
http://www.clybs.com
Thanks for this cast and comments.
I got it working with translate routes very fine.
My problem comes when I install it on a shared hosting server. Whether $config is a XML or an array, I get a Call to undefined function spl_object_hash() on this:
$navigation = New Zend_Navigation($config);
Ok, I get it:
spl_object_hash
(PHP 5 >= 5.2.0)
Cheers
i’m stuck building my navigation… i have a modular setup. The navigation is defined in an xml file.
xml file: http://pastie.org/881782
This is how I load the navigation in my bootstrap and how I set my routes
bootstrap: http://pastie.org/881770
problem is when I render the navigation the links just show the language indentifier.
ex: http://zend.test -> shows just /nl for every link in the menu
When I enter http://zend.test/nl/news the urls are renderd fine
ex: nl/news, nl/jobs …
What am I missing here?
In the navigation.xml file, if you use controller, action, & parameter tags instead of uri, I think it can determine the active node automatically. Then you can omit this part:
$activeNav = $this->view->navigation()->findByUri($uri);
$activeNav->active = true;
Very good screenshoot!
I got
Fatal error: Call to undefined method stdClass::setClass() in my application root..
After adding
Zend_Registry::set(Zend_Navigation, $container);
$container = new Zend_Navigation($config);
Zend_Registry::set(Zend_Navigation, $container);
$view->navigation($container);
also i got same error any body help me…
I have bootstrap in Zend/application folder..
I think its not correct to add this at here…
Where exactly the boot strap.php will be located?
I have zend in my foler with in php_library and with zend/application/bootstrap/bootstrap.php I put all the code within Bootstrap.php into this class….When i remove this function from bootstrap.php i got also same error. i will not effect anywhere.
Can anybody have answers..
Apparently the sitemap helper only works when the navigation.xml is uri-based and the breadcrump helper only works when the navigation is controller/action-based. That is why the $activeNav… snippet is needed in the above solution.
I have a problem when rendering menu.
On help page I have multiple sub-pages in the and I want the Help link to be active in all sub-pages.
I’ve tried with adding
$activeNav = $this->view->navigation()->findByUri(‘help’);
$activeNav->active = true;
$activeNav->setClass(“active”);
in the Help controller init() method but I get Fatal error: Call to undefined method stdClass::setClass().
When accessing the Help main page the link is active though.
Any ideas?
The xml dump:
Home
/</home
Help
/help
How to create a dynamical breadcrumb? For example: I have a blog controller with the following structure:
indexAction
artickeAction
commentsAction
How to create a breadcrumb like this (the ‘Article Name’ should be the title of the article)?
Home : Article name : Comments?
I’ve searched for quite some time now and I haven’t found a solution. Is there anyone out there who can help me?
Thanks in advance!
Hi Crispijn,
1. First prepare your menu in your bootstrap:
$config = new Zend_Config_Xml(APPLICATION_PATH.’/configs/navigation.xml’, ‘nav’);
$navigation = new Zend_Navigation($config);
$view = $this->getResource(‘view’);
$view->navigation($navigation);
2. In your layout, call your breadcrumb:
partial(‘breadcrumbs.phtml’); ?>
3. Have something like this in the breadcrumbs.phtml:
$breadcrumbs = $this->navigation()
->breadcrumbs()
->setMinDepth(0)
->setLinkLast(true)
->setSeparator(‘ | ‘);
if ($breadcrumbs != ”) print ‘You are here: ‘.$breadcrumbs.”;
Wohooo! Mabuhay ang pinoy!!
Regards,
Cliburn M. Solano
http://www.clybs.com
http://www.jamilicious.com
http://www.youtube.com/user/CLYBS
Is it possible to generate the navigation.xml file from a database? If so I would very much appreciate an example.
Thanks!
Hello,
could you help me please with next:
I want to create a menu like:
something else
.
.
What I can do for adding a tag after tag ?
Thank you.
Hello,
could you help me please with next:
I want to create a menu like:
[ul]
[li]
[a href="something"][/a]
[strong]something else[/strong]
[/li]
.
.
[/ul]
What I can do for adding a [strong] tag after tag [a] ?
Thank you.
Hi Jon,
I just want to say thank you for all the videos you’ve posted up and I must say a great contribution to Zend community.
Navigation map elements (their names) identity pages? let me rephrase: for each page there is different element type. How would it possible to process/parse it and build a schema for it?
thanks for the tut! it was great.
I could find why you have to activate the current page in the navigator:
[[ public function init()
{
parent::init();
$uri = $this->_request->getPathInfo();
$activeNave = $this->view->navigation()->findByUri($uri);
$activeNave->active = true;
}
]]
It does the work w/o it. Or maybe it is because I am using 1.10 ???
thanks!
awesome john
you rawk!
one other thing jon
after creating this whole
when i click on a menu link
all i get is blank page with the following text
“/index/[action/menulink]”
just like in the first part of your vid
where you had die($uri)
except that i dont have a die command anywhere in my code
i guess relating to that
im having a tough time making the leap from the aboutAction function
which has nothing in it
and how does link know to just to goto the /index/about view
i guess thats all taken care of by ZF?
thanks for your help
toy
Hi,
Here a plugin to use zend_navigation and breadcrumbs :
[code]class Custom_Controller_Plugin_NavigationBreadcrumbs extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
// Get the View
$view = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('view');
// Get all the links
$configNavigation = new Zend_Config_Xml(APPLICATION_PATH . '/config/navigation.xml', 'nav');
$containerNavigation = new Zend_Navigation($configNavigation);
$view->navigation($containerNavigation);
// Set the active page
$activePage = $containerNavigation->findByUri($request->getRequestUri());
$activePage->active = true;
// Get the current class and add an "active" class
$currentClass = $activePage->getClass();
$activePage->setClass($currentClass . " active");
// Assign the navigation to the view
$view->navigation($containerNavigation);
}
}[code]
How can i use setTag $activeNav? I just want change the class by strong tag? Someone can help?
Tnks!
As we rebuild the project our zendstudio 7.2.1 with the 1.10.6 zf,
shows this after building n deploying.
Fatal error: Cannot redeclare class Zend_Application in C:\xampp\htdocs\zc24-zend-navigation-breadcrumbs-sitemap-menu\library\Zend\Application.php on line 29
But we don´t know why…….
If anyone has an idea,please let us know ???
thx n best regards
the red head
Many thanks for this cast!
i am working on a multi language site. The uri’s for this site look somthing like this:
http://www.example.ch/de/module/controller/action...
My question is if there is a possibility to prepend the language part of the uri (/de) dynamicly to all the uri’s that come from the uri-sections of the navigation XML file. Because i am using Zend_Translate i would not use three different XML files for the three languages.
Regards //kurt