diff --git a/src/Helper/Navigation/Menu.php b/src/Helper/Navigation/Menu.php index c6570966..02ddff7f 100644 --- a/src/Helper/Navigation/Menu.php +++ b/src/Helper/Navigation/Menu.php @@ -20,6 +20,13 @@ */ class Menu extends AbstractHelper { + /** + * Whether page class should be applied to
  • element + * + * @var bool + */ + protected $addClassToListItem = false; + /** * Whether labels should be escaped * @@ -101,12 +108,13 @@ public function render($container = null) * Renders the deepest active menu within [$minDepth, $maxDepth], (called * from {@link renderMenu()}) * - * @param AbstractContainer $container container to render - * @param string $ulClass CSS class for first UL - * @param string $indent initial indentation - * @param int|null $minDepth minimum depth - * @param int|null $maxDepth maximum depth - * @param bool $escapeLabels Whether or not to escape the labels + * @param AbstractContainer $container container to render + * @param string $ulClass CSS class for first UL + * @param string $indent initial indentation + * @param int|null $minDepth minimum depth + * @param int|null $maxDepth maximum depth + * @param bool $escapeLabels Whether or not to escape the labels + * @param bool $addClassToListItem Whether or not page class applied to
  • element * @return string */ protected function renderDeepestMenu( @@ -115,7 +123,8 @@ protected function renderDeepestMenu( $indent, $minDepth, $maxDepth, - $escapeLabels + $escapeLabels, + $addClassToListItem ) { if (!$active = $this->findActive($container, $minDepth - 1, $maxDepth)) { return ''; @@ -141,9 +150,21 @@ protected function renderDeepestMenu( if (!$this->accept($subPage)) { continue; } - $liClass = $subPage->isActive(true) ? ' class="active"' : ''; + + // render li tag and page + $liClasses = array(); + // Is page active? + if ($subPage->isActive(true)) { + $liClasses[] = 'active'; + } + // Add CSS class from page to
  • + if ($addClassToListItem && $subPage->getClass()) { + $liClasses[] = $subPage->getClass(); + } + $liClass = empty($liClasses) ? '' : ' class="' . implode(' ', $liClasses) . '"'; + $html .= $indent . ' ' . self::EOL; - $html .= $indent . ' ' . $this->htmlify($subPage, $escapeLabels) . self::EOL; + $html .= $indent . ' ' . $this->htmlify($subPage, $escapeLabels, $addClassToListItem) . self::EOL; $html .= $indent . '
  • ' . self::EOL; } @@ -183,7 +204,9 @@ public function renderMenu($container = null, array $options = array()) $options['indent'], $options['minDepth'], $options['maxDepth'], - $options['escapeLabels']); + $options['escapeLabels'], + $options['addClassToListItem'] + ); } else { $html = $this->renderNormalMenu($container, $options['ulClass'], @@ -191,7 +214,9 @@ public function renderMenu($container = null, array $options = array()) $options['minDepth'], $options['maxDepth'], $options['onlyActiveBranch'], - $options['escapeLabels']); + $options['escapeLabels'], + $options['addClassToListItem'] + ); } return $html; @@ -200,13 +225,14 @@ public function renderMenu($container = null, array $options = array()) /** * Renders a normal menu (called from {@link renderMenu()}) * - * @param AbstractContainer $container container to render - * @param string $ulClass CSS class for first UL - * @param string $indent initial indentation - * @param int|null $minDepth minimum depth - * @param int|null $maxDepth maximum depth - * @param bool $onlyActive render only active branch? - * @param bool $escapeLabels Whether or not to escape the labels + * @param AbstractContainer $container container to render + * @param string $ulClass CSS class for first UL + * @param string $indent initial indentation + * @param int|null $minDepth minimum depth + * @param int|null $maxDepth maximum depth + * @param bool $onlyActive render only active branch? + * @param bool $escapeLabels Whether or not to escape the labels + * @param bool $addClassToListItem Whether or not page class applied to
  • element * @return string */ protected function renderNormalMenu( @@ -216,7 +242,8 @@ protected function renderNormalMenu( $minDepth, $maxDepth, $onlyActive, - $escapeLabels + $escapeLabels, + $addClassToListItem ) { $html = ''; @@ -294,9 +321,19 @@ protected function renderNormalMenu( } // render li tag and page - $liClass = $isActive ? ' class="active"' : ''; + $liClasses = array(); + // Is page active? + if ($isActive) { + $liClasses[] = 'active'; + } + // Add CSS class from page to
  • + if ($addClassToListItem && $page->getClass()) { + $liClasses[] = $page->getClass(); + } + $liClass = empty($liClasses) ? '' : ' class="' . implode(' ', $liClasses) . '"'; + $html .= $myIndent . ' ' . self::EOL - . $myIndent . ' ' . $this->htmlify($page, $escapeLabels) . self::EOL; + . $myIndent . ' ' . $this->htmlify($page, $escapeLabels, $addClassToListItem) . self::EOL; // store as previous depth for next iteration $prevDepth = $depth; @@ -410,13 +447,14 @@ public function renderSubMenu( $indent = null ) { return $this->renderMenu($container, array( - 'indent' => $indent, - 'ulClass' => $ulClass, - 'minDepth' => null, - 'maxDepth' => null, - 'onlyActiveBranch' => true, - 'renderParents' => false, - 'escapeLabels' => true + 'indent' => $indent, + 'ulClass' => $ulClass, + 'minDepth' => null, + 'maxDepth' => null, + 'onlyActiveBranch' => true, + 'renderParents' => false, + 'escapeLabels' => true, + 'addClassToListItem' => false, )); } @@ -430,7 +468,7 @@ public function renderSubMenu( * @param bool $escapeLabel Whether or not to escape the label * @return string */ - public function htmlify(AbstractPage $page, $escapeLabel = true) + public function htmlify(AbstractPage $page, $escapeLabel = true, $addClassToListItem = false) { // get label and title for translating $label = $page->getLabel(); @@ -451,9 +489,12 @@ public function htmlify(AbstractPage $page, $escapeLabel = true) $attribs = array( 'id' => $page->getId(), 'title' => $title, - 'class' => $page->getClass() ); + if ($addClassToListItem === false) { + $attribs['class'] = $page->getClass(); + } + // does page have a href? $href = $page->getHref(); if ($href) { @@ -528,6 +569,10 @@ protected function normalizeOptions(array $options = array()) $options['renderParents'] = $this->getRenderParents(); } + if (!isset($options['addClassToListItem'])) { + $options['addClassToListItem'] = $this->getAddClassToListItem(); + } + return $options; } @@ -543,6 +588,31 @@ public function escapeLabels($flag = true) return $this; } + /** + * Enables/disables page class applied to
  • element + * + * @param bool $flag [optional] page class applied to
  • element + * Default is true. + * @return Menu fluent interface, returns self + */ + public function setAddClassToListItem($flag = true) + { + $this->addClassToListItem = (bool) $flag; + return $this; + } + + /** + * Returns flag indicating whether page class should be applied to
  • element + * + * By default, this value is false. + * + * @return bool whether parents should be rendered + */ + public function getAddClassToListItem() + { + return $this->addClassToListItem; + } + /** * Sets a flag indicating whether only active branch should be rendered * diff --git a/test/Helper/Navigation/MenuTest.php b/test/Helper/Navigation/MenuTest.php index 7c147a45..89441881 100644 --- a/test/Helper/Navigation/MenuTest.php +++ b/test/Helper/Navigation/MenuTest.php @@ -520,6 +520,58 @@ public function testOptionOnlyActiveBranchNoParentsAndBothDepthsSpecified() $this->assertEquals($expected, $actual); } + public function testRenderingWithoutPageClassToLi() + { + $container = new \Zend\Navigation\Navigation($this->_nav2->toArray()); + $container->addPage(array( + 'label' => 'Class test', + 'uri' => 'test', + 'class' => 'foobar', + )); + + $expected = $this->_getExpected('menu/addclasstolistitem_as_false.html'); + $actual = $this->_helper->renderMenu($container); + + $this->assertEquals($expected, $actual); + } + + public function testRenderingWithPageClassToLi() + { + $options = array( + 'addClassToListItem' => true, + ); + + $container = new \Zend\Navigation\Navigation($this->_nav2->toArray()); + $container->addPage(array( + 'label' => 'Class test', + 'uri' => 'test', + 'class' => 'foobar', + )); + + $expected = $this->_getExpected('menu/addclasstolistitem_as_true.html'); + $actual = $this->_helper->renderMenu($container, $options); + + $this->assertEquals($expected, $actual); + } + + public function testRenderDeepestMenuWithPageClassToLi() + { + $options = array( + 'addClassToListItem' => true, + 'onlyActiveBranch' => true, + 'renderParents' => false, + ); + + $pages = $this->_nav2->toArray(); + $pages[1]['class'] = 'foobar'; + $container = new \Zend\Navigation\Navigation($pages); + + $expected = $this->_getExpected('menu/onlyactivebranch_addclasstolistitem.html'); + $actual = $this->_helper->renderMenu($container, $options); + + $this->assertEquals($expected, $actual); + } + /** * Returns the contens of the expected $file, normalizes newlines * @param string $file diff --git a/test/Helper/Navigation/_files/expected/menu/addclasstolistitem_as_false.html b/test/Helper/Navigation/_files/expected/menu/addclasstolistitem_as_false.html new file mode 100644 index 00000000..f3b66dee --- /dev/null +++ b/test/Helper/Navigation/_files/expected/menu/addclasstolistitem_as_false.html @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/test/Helper/Navigation/_files/expected/menu/addclasstolistitem_as_true.html b/test/Helper/Navigation/_files/expected/menu/addclasstolistitem_as_true.html new file mode 100644 index 00000000..dc0eaee6 --- /dev/null +++ b/test/Helper/Navigation/_files/expected/menu/addclasstolistitem_as_true.html @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/test/Helper/Navigation/_files/expected/menu/onlyactivebranch_addclasstolistitem.html b/test/Helper/Navigation/_files/expected/menu/onlyactivebranch_addclasstolistitem.html new file mode 100644 index 00000000..8c50053f --- /dev/null +++ b/test/Helper/Navigation/_files/expected/menu/onlyactivebranch_addclasstolistitem.html @@ -0,0 +1,11 @@ + \ No newline at end of file