Menu.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_View
  17. * @subpackage Helper
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @see Zend_View_Helper_Navigation_HelperAbstract
  24. */
  25. require_once 'Zend/View/Helper/Navigation/HelperAbstract.php';
  26. /**
  27. * Helper for rendering menus from navigation containers
  28. *
  29. * @category Zend
  30. * @package Zend_View
  31. * @subpackage Helper
  32. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  33. * @license http://framework.zend.com/license/new-bsd New BSD License
  34. */
  35. class Zend_View_Helper_Navigation_Menu
  36. extends Zend_View_Helper_Navigation_HelperAbstract
  37. {
  38. /**
  39. * CSS class to use for the ul element
  40. *
  41. * @var string
  42. */
  43. protected $_ulClass = 'navigation';
  44. /**
  45. * Unique identifier (id) for the ul element
  46. *
  47. * @var string
  48. */
  49. protected $_ulId = null;
  50. /**
  51. * Whether only active branch should be rendered
  52. *
  53. * @var bool
  54. */
  55. protected $_onlyActiveBranch = false;
  56. /**
  57. * Whether parents should be rendered when only rendering active branch
  58. *
  59. * @var bool
  60. */
  61. protected $_renderParents = true;
  62. /**
  63. * Partial view script to use for rendering menu
  64. *
  65. * @var string|array
  66. */
  67. protected $_partial = null;
  68. /**
  69. * Expand all sibling nodes of active branch nodes
  70. */
  71. protected $_expandSiblingNodesOfActiveBranch = false;
  72. /**
  73. * View helper entry point:
  74. * Retrieves helper and optionally sets container to operate on
  75. *
  76. * @param Zend_Navigation_Container $container [optional] container to
  77. * operate on
  78. * @return Zend_View_Helper_Navigation_Menu fluent interface,
  79. * returns self
  80. */
  81. public function menu(Zend_Navigation_Container $container = null)
  82. {
  83. if (null !== $container) {
  84. $this->setContainer($container);
  85. }
  86. return $this;
  87. }
  88. // Accessors:
  89. /**
  90. * Sets CSS class to use for the first 'ul' element when rendering
  91. *
  92. * @param string $ulClass CSS class to set
  93. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
  94. */
  95. public function setUlClass($ulClass)
  96. {
  97. if (is_string($ulClass)) {
  98. $this->_ulClass = $ulClass;
  99. }
  100. return $this;
  101. }
  102. /**
  103. * Returns CSS class to use for the first 'ul' element when rendering
  104. *
  105. * @return string CSS class
  106. */
  107. public function getUlClass()
  108. {
  109. return $this->_ulClass;
  110. }
  111. /**
  112. * Sets unique identifier (id) to use for the first 'ul' element when
  113. * rendering
  114. *
  115. * @param string|null $ulId Unique identifier (id) to set
  116. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
  117. */
  118. public function setUlId($ulId)
  119. {
  120. if (is_string($ulId)) {
  121. $this->_ulId = $ulId;
  122. }
  123. return $this;
  124. }
  125. /**
  126. * Returns unique identifier (id) to use for the first 'ul' element when
  127. * rendering
  128. *
  129. * @return string|null Unique identifier (id); Default is 'null'
  130. */
  131. public function getUlId()
  132. {
  133. return $this->_ulId;
  134. }
  135. /**
  136. * Sets a flag indicating whether only active branch should be rendered
  137. *
  138. * @param bool $flag [optional] render only active
  139. * branch. Default is true.
  140. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
  141. */
  142. public function setOnlyActiveBranch($flag = true)
  143. {
  144. $this->_onlyActiveBranch = (bool) $flag;
  145. return $this;
  146. }
  147. /**
  148. * Returns a flag indicating whether only active branch should be rendered
  149. *
  150. * By default, this value is false, meaning the entire menu will be
  151. * be rendered.
  152. *
  153. * @return bool whether only active branch should be rendered
  154. */
  155. public function getOnlyActiveBranch()
  156. {
  157. return $this->_onlyActiveBranch;
  158. }
  159. /**
  160. * Sets a flag indicating whether to expand all sibling nodes of the active branch
  161. *
  162. * @param bool $flag [optional] expand all siblings of
  163. * nodes in the active branch. Default is true.
  164. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
  165. */
  166. public function setExpandSiblingNodesOfActiveBranch($flag = true)
  167. {
  168. $this->_expandSiblingNodesOfActiveBranch = (bool) $flag;
  169. return $this;
  170. }
  171. /**
  172. * Returns a flag indicating whether to expand all sibling nodes of the active branch
  173. *
  174. * By default, this value is false, meaning the entire menu will be
  175. * be rendered.
  176. *
  177. * @return bool whether siblings of nodes in the active branch should be expanded
  178. */
  179. public function getExpandSiblingNodesOfActiveBranch()
  180. {
  181. return $this->_expandSiblingNodesOfActiveBranch;
  182. }
  183. /**
  184. * Enables/disables rendering of parents when only rendering active branch
  185. *
  186. * See {@link setOnlyActiveBranch()} for more information.
  187. *
  188. * @param bool $flag [optional] render parents when
  189. * rendering active branch.
  190. * Default is true.
  191. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
  192. */
  193. public function setRenderParents($flag = true)
  194. {
  195. $this->_renderParents = (bool) $flag;
  196. return $this;
  197. }
  198. /**
  199. * Returns flag indicating whether parents should be rendered when rendering
  200. * only the active branch
  201. *
  202. * By default, this value is true.
  203. *
  204. * @return bool whether parents should be rendered
  205. */
  206. public function getRenderParents()
  207. {
  208. return $this->_renderParents;
  209. }
  210. /**
  211. * Sets which partial view script to use for rendering menu
  212. *
  213. * @param string|array $partial partial view script or null. If
  214. * an array is given, it is
  215. * expected to contain two values;
  216. * the partial view script to use,
  217. * and the module where the script
  218. * can be found.
  219. * @return Zend_View_Helper_Navigation_Menu fluent interface, returns self
  220. */
  221. public function setPartial($partial)
  222. {
  223. if (null === $partial || is_string($partial) || is_array($partial)) {
  224. $this->_partial = $partial;
  225. }
  226. return $this;
  227. }
  228. /**
  229. * Returns partial view script to use for rendering menu
  230. *
  231. * @return string|array|null
  232. */
  233. public function getPartial()
  234. {
  235. return $this->_partial;
  236. }
  237. // Public methods:
  238. /**
  239. * Returns an HTML string containing an 'a' element for the given page if
  240. * the page's href is not empty, and a 'span' element if it is empty
  241. *
  242. * Overrides {@link Zend_View_Helper_Navigation_Abstract::htmlify()}.
  243. *
  244. * @param Zend_Navigation_Page $page page to generate HTML for
  245. * @return string HTML string for the given page
  246. */
  247. public function htmlify(Zend_Navigation_Page $page)
  248. {
  249. // get label and title for translating
  250. $label = $page->getLabel();
  251. $title = $page->getTitle();
  252. // translate label and title?
  253. if ($this->getUseTranslator() && $t = $this->getTranslator()) {
  254. if (is_string($label) && !empty($label)) {
  255. $label = $t->translate($label);
  256. }
  257. if (is_string($title) && !empty($title)) {
  258. $title = $t->translate($title);
  259. }
  260. }
  261. // get attribs for element
  262. $attribs = array(
  263. 'id' => $page->getId(),
  264. 'title' => $title,
  265. 'class' => $page->getClass()
  266. );
  267. // does page have a href?
  268. if ($href = $page->getHref()) {
  269. $element = 'a';
  270. $attribs['href'] = $href;
  271. $attribs['target'] = $page->getTarget();
  272. $attribs['accesskey'] = $page->getAccessKey();
  273. } else {
  274. $element = 'span';
  275. }
  276. // Add custom HTML attributes
  277. $attribs = array_merge($attribs, $page->getCustomHtmlAttribs());
  278. return '<' . $element . $this->_htmlAttribs($attribs) . '>'
  279. . $this->view->escape($label)
  280. . '</' . $element . '>';
  281. }
  282. /**
  283. * Normalizes given render options
  284. *
  285. * @param array $options [optional] options to normalize
  286. * @return array normalized options
  287. */
  288. protected function _normalizeOptions(array $options = array())
  289. {
  290. if (isset($options['indent'])) {
  291. $options['indent'] = $this->_getWhitespace($options['indent']);
  292. } else {
  293. $options['indent'] = $this->getIndent();
  294. }
  295. if (isset($options['ulClass']) && $options['ulClass'] !== null) {
  296. $options['ulClass'] = (string) $options['ulClass'];
  297. } else {
  298. $options['ulClass'] = $this->getUlClass();
  299. }
  300. if (isset($options['ulId']) && $options['ulId'] !== null) {
  301. $options['ulId'] = (string) $options['ulId'];
  302. } else {
  303. $options['ulId'] = $this->getUlId();
  304. }
  305. if (array_key_exists('minDepth', $options)) {
  306. if (null !== $options['minDepth']) {
  307. $options['minDepth'] = (int) $options['minDepth'];
  308. }
  309. } else {
  310. $options['minDepth'] = $this->getMinDepth();
  311. }
  312. if ($options['minDepth'] < 0 || $options['minDepth'] === null) {
  313. $options['minDepth'] = 0;
  314. }
  315. // Maximum depth
  316. if (array_key_exists('maxDepth', $options)) {
  317. if (null !== $options['maxDepth']) {
  318. $options['maxDepth'] = (int) $options['maxDepth'];
  319. }
  320. } else {
  321. $options['maxDepth'] = $this->getMaxDepth();
  322. }
  323. if (!isset($options['onlyActiveBranch'])) {
  324. $options['onlyActiveBranch'] = $this->getOnlyActiveBranch();
  325. }
  326. if (!isset($options['expandSiblingNodesOfActiveBranch'])) {
  327. $options['expandSiblingNodesOfActiveBranch'] = $this->getExpandSiblingNodesOfActiveBranch();
  328. }
  329. if (!isset($options['renderParents'])) {
  330. $options['renderParents'] = $this->getRenderParents();
  331. }
  332. return $options;
  333. }
  334. // Render methods:
  335. /**
  336. * Renders the deepest active menu within [$minDepth, $maxDeth], (called
  337. * from {@link renderMenu()})
  338. *
  339. * @param Zend_Navigation_Container $container container to render
  340. * @param array $active active page and depth
  341. * @param string $ulClass CSS class for first UL
  342. * @param string $indent initial indentation
  343. * @param int|null $minDepth minimum depth
  344. * @param int|null $maxDepth maximum depth
  345. * @param string|null $ulId unique identifier (id) for
  346. * first UL
  347. * @return string rendered menu
  348. */
  349. protected function _renderDeepestMenu(Zend_Navigation_Container $container,
  350. $ulClass,
  351. $indent,
  352. $minDepth,
  353. $maxDepth,
  354. $ulId)
  355. {
  356. if (!$active = $this->findActive($container, $minDepth - 1, $maxDepth)) {
  357. return '';
  358. }
  359. // special case if active page is one below minDepth
  360. if ($active['depth'] < $minDepth) {
  361. if (!$active['page']->hasPages()) {
  362. return '';
  363. }
  364. } else if (!$active['page']->hasPages()) {
  365. // found pages has no children; render siblings
  366. $active['page'] = $active['page']->getParent();
  367. } else if (is_int($maxDepth) && $active['depth'] +1 > $maxDepth) {
  368. // children are below max depth; render siblings
  369. $active['page'] = $active['page']->getParent();
  370. }
  371. $attribs = array(
  372. 'class' => $ulClass,
  373. 'id' => $ulId,
  374. );
  375. // We don't need a prefix for the menu ID (backup)
  376. $skipValue = $this->_skipPrefixForId;
  377. $this->skipPrefixForId();
  378. $html = $indent . '<ul'
  379. . $this->_htmlAttribs($attribs)
  380. . '>'
  381. . self::EOL;
  382. // Reset prefix for IDs
  383. $this->_skipPrefixForId = $skipValue;
  384. foreach ($active['page'] as $subPage) {
  385. if (!$this->accept($subPage)) {
  386. continue;
  387. }
  388. $liClass = $subPage->isActive(true) ? ' class="active"' : '';
  389. $html .= $indent . ' <li' . $liClass . '>' . self::EOL;
  390. $html .= $indent . ' ' . $this->htmlify($subPage) . self::EOL;
  391. $html .= $indent . ' </li>' . self::EOL;
  392. }
  393. $html .= $indent . '</ul>';
  394. return $html;
  395. }
  396. /**
  397. * Renders a normal menu (called from {@link renderMenu()})
  398. *
  399. * @param Zend_Navigation_Container $container container to render
  400. * @param string $ulClass CSS class for first UL
  401. * @param string $indent initial indentation
  402. * @param int|null $minDepth minimum depth
  403. * @param int|null $maxDepth maximum depth
  404. * @param bool $onlyActive render only active branch?
  405. * @param bool $expandSibs render siblings of active
  406. * branch nodes?
  407. * @param string|null $ulId unique identifier (id) for
  408. * first UL
  409. * @return string
  410. */
  411. protected function _renderMenu(Zend_Navigation_Container $container,
  412. $ulClass,
  413. $indent,
  414. $minDepth,
  415. $maxDepth,
  416. $onlyActive,
  417. $expandSibs,
  418. $ulId)
  419. {
  420. $html = '';
  421. // find deepest active
  422. if ($found = $this->findActive($container, $minDepth, $maxDepth)) {
  423. $foundPage = $found['page'];
  424. $foundDepth = $found['depth'];
  425. } else {
  426. $foundPage = null;
  427. }
  428. // create iterator
  429. $iterator = new RecursiveIteratorIterator($container,
  430. RecursiveIteratorIterator::SELF_FIRST);
  431. if (is_int($maxDepth)) {
  432. $iterator->setMaxDepth($maxDepth);
  433. }
  434. // iterate container
  435. $prevDepth = -1;
  436. foreach ($iterator as $page) {
  437. $depth = $iterator->getDepth();
  438. $isActive = $page->isActive(true);
  439. if ($depth < $minDepth || !$this->accept($page)) {
  440. // page is below minDepth or not accepted by acl/visibilty
  441. continue;
  442. } else if ($expandSibs && $depth > $minDepth) {
  443. // page is not active itself, but might be in the active branch
  444. $accept = false;
  445. if ($foundPage) {
  446. if ($foundPage->hasPage($page)) {
  447. // accept if page is a direct child of the active page
  448. $accept = true;
  449. } else if ($page->getParent()->isActive(true)) {
  450. // page is a sibling of the active branch...
  451. $accept = true;
  452. }
  453. }
  454. if (!$isActive && !$accept) {
  455. continue;
  456. }
  457. } else if ($onlyActive && !$isActive) {
  458. // page is not active itself, but might be in the active branch
  459. $accept = false;
  460. if ($foundPage) {
  461. if ($foundPage->hasPage($page)) {
  462. // accept if page is a direct child of the active page
  463. $accept = true;
  464. } else if ($foundPage->getParent()->hasPage($page)) {
  465. // page is a sibling of the active page...
  466. if (!$foundPage->hasPages() ||
  467. is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
  468. // accept if active page has no children, or the
  469. // children are too deep to be rendered
  470. $accept = true;
  471. }
  472. }
  473. }
  474. if (!$accept) {
  475. continue;
  476. }
  477. }
  478. // make sure indentation is correct
  479. $depth -= $minDepth;
  480. $myIndent = $indent . str_repeat(' ', $depth);
  481. if ($depth > $prevDepth) {
  482. $attribs = array();
  483. // start new ul tag
  484. if (0 == $depth) {
  485. $attribs = array(
  486. 'class' => $ulClass,
  487. 'id' => $ulId,
  488. );
  489. }
  490. // We don't need a prefix for the menu ID (backup)
  491. $skipValue = $this->_skipPrefixForId;
  492. $this->skipPrefixForId();
  493. $html .= $myIndent . '<ul'
  494. . $this->_htmlAttribs($attribs)
  495. . '>'
  496. . self::EOL;
  497. // Reset prefix for IDs
  498. $this->_skipPrefixForId = $skipValue;
  499. } else if ($prevDepth > $depth) {
  500. // close li/ul tags until we're at current depth
  501. for ($i = $prevDepth; $i > $depth; $i--) {
  502. $ind = $indent . str_repeat(' ', $i);
  503. $html .= $ind . ' </li>' . self::EOL;
  504. $html .= $ind . '</ul>' . self::EOL;
  505. }
  506. // close previous li tag
  507. $html .= $myIndent . ' </li>' . self::EOL;
  508. } else {
  509. // close previous li tag
  510. $html .= $myIndent . ' </li>' . self::EOL;
  511. }
  512. // render li tag and page
  513. $liClass = $isActive ? ' class="active"' : '';
  514. $html .= $myIndent . ' <li' . $liClass . '>' . self::EOL
  515. . $myIndent . ' ' . $this->htmlify($page) . self::EOL;
  516. // store as previous depth for next iteration
  517. $prevDepth = $depth;
  518. }
  519. if ($html) {
  520. // done iterating container; close open ul/li tags
  521. for ($i = $prevDepth+1; $i > 0; $i--) {
  522. $myIndent = $indent . str_repeat(' ', $i-1);
  523. $html .= $myIndent . ' </li>' . self::EOL
  524. . $myIndent . '</ul>' . self::EOL;
  525. }
  526. $html = rtrim($html, self::EOL);
  527. }
  528. return $html;
  529. }
  530. /**
  531. * Renders helper
  532. *
  533. * Renders a HTML 'ul' for the given $container. If $container is not given,
  534. * the container registered in the helper will be used.
  535. *
  536. * Available $options:
  537. *
  538. *
  539. * @param Zend_Navigation_Container $container [optional] container to
  540. * create menu from. Default
  541. * is to use the container
  542. * retrieved from
  543. * {@link getContainer()}.
  544. * @param array $options [optional] options for
  545. * controlling rendering
  546. * @return string rendered menu
  547. */
  548. public function renderMenu(Zend_Navigation_Container $container = null,
  549. array $options = array())
  550. {
  551. if (null === $container) {
  552. $container = $this->getContainer();
  553. }
  554. $options = $this->_normalizeOptions($options);
  555. if ($options['onlyActiveBranch'] && !$options['renderParents']) {
  556. $html = $this->_renderDeepestMenu($container,
  557. $options['ulClass'],
  558. $options['indent'],
  559. $options['minDepth'],
  560. $options['maxDepth'],
  561. $options['ulId']);
  562. } else {
  563. $html = $this->_renderMenu($container,
  564. $options['ulClass'],
  565. $options['indent'],
  566. $options['minDepth'],
  567. $options['maxDepth'],
  568. $options['onlyActiveBranch'],
  569. $options['expandSiblingNodesOfActiveBranch'],
  570. $options['ulId']);
  571. }
  572. return $html;
  573. }
  574. /**
  575. * Renders the inner-most sub menu for the active page in the $container
  576. *
  577. * This is a convenience method which is equivalent to the following call:
  578. * <code>
  579. * renderMenu($container, array(
  580. * 'indent' => $indent,
  581. * 'ulClass' => $ulClass,
  582. * 'minDepth' => null,
  583. * 'maxDepth' => null,
  584. * 'onlyActiveBranch' => true,
  585. * 'renderParents' => false
  586. * ));
  587. * </code>
  588. *
  589. * @param Zend_Navigation_Container $container [optional] container to
  590. * render. Default is to render
  591. * the container registered in
  592. * the helper.
  593. * @param string|null $ulClass [optional] CSS class to
  594. * use for UL element. Default
  595. * is to use the value from
  596. * {@link getUlClass()}.
  597. * @param string|int $indent [optional] indentation as
  598. * a string or number of
  599. * spaces. Default is to use
  600. * the value retrieved from
  601. * {@link getIndent()}.
  602. * @param string|null $ulId [optional] Unique identifier
  603. * (id) use for UL element
  604. * @return string rendered content
  605. */
  606. public function renderSubMenu(Zend_Navigation_Container $container = null,
  607. $ulClass = null,
  608. $indent = null,
  609. $ulId = null)
  610. {
  611. return $this->renderMenu($container, array(
  612. 'indent' => $indent,
  613. 'ulClass' => $ulClass,
  614. 'minDepth' => null,
  615. 'maxDepth' => null,
  616. 'onlyActiveBranch' => true,
  617. 'renderParents' => false,
  618. 'ulId' => $ulId,
  619. ));
  620. }
  621. /**
  622. * Renders the given $container by invoking the partial view helper
  623. *
  624. * The container will simply be passed on as a model to the view script
  625. * as-is, and will be available in the partial script as 'container', e.g.
  626. * <code>echo 'Number of pages: ', count($this->container);</code>.
  627. *
  628. * @param Zend_Navigation_Container $container [optional] container to
  629. * pass to view script. Default
  630. * is to use the container
  631. * registered in the helper.
  632. * @param string|array $partial [optional] partial view
  633. * script to use. Default is to
  634. * use the partial registered
  635. * in the helper. If an array
  636. * is given, it is expected to
  637. * contain two values; the
  638. * partial view script to use,
  639. * and the module where the
  640. * script can be found.
  641. * @return string helper output
  642. */
  643. public function renderPartial(Zend_Navigation_Container $container = null,
  644. $partial = null)
  645. {
  646. if (null === $container) {
  647. $container = $this->getContainer();
  648. }
  649. if (null === $partial) {
  650. $partial = $this->getPartial();
  651. }
  652. if (empty($partial)) {
  653. require_once 'Zend/View/Exception.php';
  654. $e = new Zend_View_Exception(
  655. 'Unable to render menu: No partial view script provided'
  656. );
  657. $e->setView($this->view);
  658. throw $e;
  659. }
  660. $model = array(
  661. 'container' => $container
  662. );
  663. if (is_array($partial)) {
  664. if (count($partial) != 2) {
  665. require_once 'Zend/View/Exception.php';
  666. $e = new Zend_View_Exception(
  667. 'Unable to render menu: A view partial supplied as '
  668. . 'an array must contain two values: partial view '
  669. . 'script and module where script can be found'
  670. );
  671. $e->setView($this->view);
  672. throw $e;
  673. }
  674. return $this->view->partial($partial[0], $partial[1], $model);
  675. }
  676. return $this->view->partial($partial, null, $model);
  677. }
  678. // Zend_View_Helper_Navigation_Helper:
  679. /**
  680. * Renders menu
  681. *
  682. * Implements {@link Zend_View_Helper_Navigation_Helper::render()}.
  683. *
  684. * If a partial view is registered in the helper, the menu will be rendered
  685. * using the given partial script. If no partial is registered, the menu
  686. * will be rendered as an 'ul' element by the helper's internal method.
  687. *
  688. * @see renderPartial()
  689. * @see renderMenu()
  690. *
  691. * @param Zend_Navigation_Container $container [optional] container to
  692. * render. Default is to
  693. * render the container
  694. * registered in the helper.
  695. * @return string helper output
  696. */
  697. public function render(Zend_Navigation_Container $container = null)
  698. {
  699. if ($partial = $this->getPartial()) {
  700. return $this->renderPartial($container, $partial);
  701. } else {
  702. return $this->renderMenu($container);
  703. }
  704. }
  705. }