Zend Navigation has a menu helper class that can output a basic nested UL menu. You can set id/class attributes on the A elements, and it adds an “active” classname to A elements in the active branch, but customizing the markup beyond that gets complicated. Attempting to duplicate the markup of an existing mega-menu, I had several goals:
- allow custom attributes on the LIs and submenu menu ULs
- allow HTML labels that were not to be escaped
- allow custom content before/after the submenu ULs
- allow specifying (1), (2), and (3) from custom properties on the page objects
- automatically add classnames to the ULs based on depth
- automatically add DIV wrappers around the ULs based on depth
- add custom classnames to LIs to indicate the active page, the parent LI above the active page’s LI, and the LI at the top level of the active branch
- have separate rendering methods for active/inactive links (e.g. you could subclass to use a STRONG to wrap the active page label instead of a link)
I first extended the helper and overrode _renderMenu(), but quickly found that its recursive iterator—while making it possible to reach all pages in a single loop—makes it really awkward to generate markup. Particularly, specifying content to come after a submenu is pretty much impossible due to the unpredictable way the iterator walks through the tree. Although maybe a little slower, switching to recursive methods made customization much more straightforward.
The result is this MegaMenu helper (see example usage).
In theory, one is supposed to use view partials for customization, but the documentation doesn’t provide much guidance here. You’d still have to recursively render several templates, which would arguably perform even worse than recursive method calls.
Caveats: (1) To offset the added memory footprint, I removed all other features from my helper: it can only render the whole page tree and has no regard for ACLs/visibility, but these shouldn’t be terribly difficult to add back in. (2) One can argue the wisdom of embedding markup in the page objects. HTML labels could make your menu more difficult to use with Zend’s breadcrumb helper.