Search code examples
phpzend-frameworkzend-navigationzend-framework-mvc

Zend_Navigation_Page_Mvc and Fragment Identifiers


I use Zend_Navigation on my site. Most of the items are Zend_Navigation_Page_Mvc and NOT Zend_Navigation_Page_Uri. I know that I can easily add a fragment identifier to a Zend_Navigation_Page_Uri item, but that's not the elegant solution I'm looking for. There are a couple of solutions on this post, but they extend the URL helper and don't affect navigation.

I already use a sub-classed Zend_View_Helper_Navigation_Menu to render the menus. Maybe there's a way to accomplish this with the htmlify() function?


Solution

  • I ended up adding a property called fragment to the page array passed into Zend_Navigation and then checking for it in my sub-classed Zend_View_Helper_Navigation_Menu::htmlify(). Here is my htmlify() code:

    /**
     * Returns an HTML string containing an 'a' element for the given page if
     * the page's href is not empty, and a 'span' element if it is empty
     *
     * Overrides {@link Zend_View_Helper_Navigation_Abstract::htmlify()}.
     *
     * @param  Zend_Navigation_Page $page  page to generate HTML for
     * @return string                      HTML string for the given page
     */
    public function htmlify(Zend_Navigation_Page $page)
    {
        // get label and title for translating
        $label = $page->getLabel();
        $title = $page->getTitle();
    
        // translate label and title?
        if ($this->getUseTranslator() && $t = $this->getTranslator()) {
            if (is_string($label) && !empty($label)) {
                $label = $t->translate($label);
            }
            if (is_string($title) && !empty($title)) {
                $title = $t->translate($title);
            }
        }
    
        // get attribs for element
        $attribs = array(
            'id'     => $page->getId(),
            'title'  => $title,
            'class'  => $page->getClass()
        );
    
        // does page have a href?
        if ($href = $page->getHref()) {
            $element = 'a';
            $attribs['href'] = $href;
            $attribs['target'] = $page->getTarget();
            // fragment identifier
            if (0 < strlen($fragment = $page->get('fragment'))) {
                $attribs['href'] .= '#' . $fragment;
            }
        } else {
            $element = 'span';
        }
    
        return '<' . $element . $this->_htmlAttribs($attribs) . '><span>'
             . $this->view->escape($label)
             . '</span></' . $element . '>';
    }