Permalink
Browse files

- removed startMenu() and startRow() methods from Renderer

- DirectRenderer's output is now customizable
- reworked prevnext menu generation, previous element is now the closest to the current


git-svn-id: http://svn.php.net/repository/pear/packages/HTML_Menu/trunk@140017 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information...
1 parent dec1ec8 commit 9710b03f605738416a9b741aef221a944d545847 @sad-spirit sad-spirit committed Sep 10, 2003
Showing with 146 additions and 144 deletions.
  1. +34 −54 Menu.php
  2. +107 −63 Menu/DirectRenderer.php
  3. +5 −27 Menu/Renderer.php
View
@@ -289,24 +289,19 @@ function _findNodeType($nodeId, $nodeUrl, $level)
*/
function _renderTree($menu, $level = 0)
{
- if (0 == $level) {
- $this->_renderer->startMenu();
- }
- // loop through the (sub)menu
foreach ($menu as $node_id => $node) {
$type = $this->_findNodeType($node_id, $node['url'], $level);
- $this->_renderer->startRow();
$this->_renderer->renderEntry($node, $level, $type);
- $this->_renderer->finishRow();
+ $this->_renderer->finishRow($level);
- // follow the subtree if the active menu item is in it
+ // follow the subtree if the active menu item is in it or if we want the full menu
if (('sitemap' == $this->_menuType || HTML_MENU_ENTRY_INACTIVE != $type) && isset($node['sub'])) {
$this->_renderTree($node['sub'], $level + 1);
}
}
if (0 == $level) {
- $this->_renderer->finishMenu();
+ $this->_renderer->finishMenu($level);
}
}
@@ -320,25 +315,20 @@ function _renderTree($menu, $level = 0)
*/
function _renderURHere($menu, $level = 0)
{
- if (0 == $level) {
- $this->_renderer->startMenu();
- $this->_renderer->startRow();
- }
foreach ($menu as $node_id => $node) {
$type = $this->_findNodeType($node_id, $node['url'], $level);
if (HTML_MENU_ENTRY_INACTIVE != $type) {
$this->_renderer->renderEntry($node, $level, $type);
- }
-
- // follow the subtree if the active menu item is in it
- if (HTML_MENU_ENTRY_INACTIVE != $type && isset($node['sub'])) {
- $this->_renderURHere($node['sub'], $level + 1);
+ // follow the subtree if the active menu item is in it
+ if (isset($node['sub'])) {
+ $this->_renderURHere($node['sub'], $level + 1);
+ }
}
}
if (0 == $level) {
- $this->_renderer->finishRow();
- $this->_renderer->finishMenu();
+ $this->_renderer->finishRow($level);
+ $this->_renderer->finishMenu($level);
}
}
@@ -352,10 +342,6 @@ function _renderURHere($menu, $level = 0)
*/
function _renderRows($menu, $level = 0)
{
- // every (sub)menu has it's own table
- $this->_renderer->startMenu();
- $this->_renderer->startRow();
-
$submenu = false;
foreach ($menu as $node_id => $node) {
@@ -369,8 +355,9 @@ function _renderRows($menu, $level = 0)
}
}
- $this->_renderer->finishRow();
- $this->_renderer->finishMenu();
+ // every (sub)menu has its own table
+ $this->_renderer->finishRow($level);
+ $this->_renderer->finishMenu($level);
// go deeper if neccessary
if ($submenu) {
@@ -386,28 +373,25 @@ function _renderRows($menu, $level = 0)
* @param array (sub)menu being rendered
* @param int current depth in the tree structure
* @param int flag indicating whether to finish processing
+ * (0 - continue, 1 - this is "next" node, 2 - stop)
*/
- function _renderPrevNext($menu, $level = 0, $flagStopLevel = -1)
+ function _renderPrevNext($menu, $level = 0, $flagStop = 0)
{
static $last_node = array(), $up_node = array();
- if (0 == $level) {
- $this->_renderer->startMenu();
- $this->_renderer->startRow();
- }
foreach ($menu as $node_id => $node) {
- if (-1 != $flagStopLevel) {
+ if (0 != $flagStop) {
// add this item to the menu and stop recursion - (next >>) node
- if ($flagStopLevel == $level) {
+ if ($flagStop == 1) {
$this->_renderer->renderEntry($node, $level, HTML_MENU_ENTRY_NEXT);
- $flagStopLevel = -1;
+ $flagStop = 2;
}
break;
} else {
$type = $this->_findNodeType($node_id, $node['url'], $level);
if (HTML_MENU_ENTRY_ACTIVE == $type) {
- $flagStopLevel = $level;
+ $flagStop = 1;
// WARNING: if there's no previous take the first menu entry - you might not like this rule!
if (0 == count($last_node)) {
@@ -428,31 +412,32 @@ function _renderPrevNext($menu, $level = 0, $flagStopLevel = -1)
// remember the last (<< prev) node
$last_node = $node;
- // follow the subtree if the active menu item is in it
- if ((HTML_MENU_ENTRY_INACTIVE != $type) && isset($node['sub'])) {
- $up_node = $node;
- $flagStopLevel = $this->_renderPrevNext($node['sub'], $level + 1, (-1 != $flagStopLevel) ? $flagStopLevel + 1 : -1);
+ if (isset($node['sub'])) {
+ if (HTML_MENU_ENTRY_INACTIVE != $type) {
+ $up_node = $node;
+ }
+ $flagStop = $this->_renderPrevNext($node['sub'], $level + 1, $flagStop);
}
}
if (0 == $level) {
- $this->_renderer->finishRow();
- $this->_renderer->finishMenu();
+ $this->_renderer->finishRow($level);
+ $this->_renderer->finishMenu($level);
}
- return ($flagStopLevel) ? $flagStopLevel - 1 : -1;
+ return $flagStop;
}
/**
* Returns the path of the current page in the menu 'tree'.
*
* @return array path to the selected menu item
- * @see _buildPath(), $urlmap
+ * @see _buildUrlMap(), $_urlMap
*/
function getPath()
{
$this->_currentUrl = $this->getCurrentURL();
- $this->_buildPath($this->_menu, array());
+ $this->_buildUrlMap($this->_menu, array());
// If there is no match for the current URL, try to come up with
// the best approximation by shortening the url
@@ -465,15 +450,15 @@ function getPath()
/**
- * Computes the path of the current page in the menu 'tree'.
+ * Builds the mappings from node url to the 'path' in the menu
*
* @access private
* @param array (sub)menu being processed
* @param array path to the (sub)menu
* @return boolean true if the path to the current page was found, otherwise false.
- * @see getPath(), $urlmap
+ * @see getPath(), $_urlMap
*/
- function _buildPath($menu, $path)
+ function _buildUrlMap($menu, $path)
{
foreach ($menu as $nodeId => $node) {
$this->_urlMap[$node['url']] = $path;
@@ -482,14 +467,9 @@ function _buildPath($menu, $path)
return true;
}
- if (isset($node['sub'])) {
- // submenu path = current path + current node
- $subpath = $path;
- $subpath[] = $nodeId;
-
- if ($this->_buildPath($node['sub'], $subpath)) {
- return true;
- }
+ if (isset($node['sub']) &&
+ $this->_buildUrlMap($node['sub'], array_merge($path, array($nodeId)))) {
+ return true;
}
}
return false;
@@ -24,10 +24,9 @@
require_once 'HTML/Menu/Renderer.php';
/**
- * The renderer that generates HTML for the menu itself.
+ * The renderer that generates HTML for the menu all by itself.
*
- * Based on HTML_Menu 1.0 code
- * XXX: no output customization for now (except for subclassing this). BAD.
+ * Inspired by HTML_Menu 1.0 code
*
* @version $Revision$
* @author Ulf Wendel <ulf.wendel@phpdoc.de>
@@ -43,77 +42,72 @@ class HTML_Menu_DirectRenderer extends HTML_Menu_Renderer
*/
var $_html = '';
- function startMenu()
- {
- $this->_html .= '<table border="1">';
- }
+ /**
+ * Generated HTML for the current menu "table"
+ * @var string
+ */
+ var $_tableHtml = '';
+
+ /**
+ * Generated HTML for the current menu "row"
+ * @var string
+ */
+ var $_rowHtml = '';
- function finishMenu()
- {
- $this->_html .= '</table>';
- }
+ /**
+ * The HTML that will wrap around menu "table"
+ * @see setMenuTemplate()
+ * @var array
+ */
+ var $_menuTemplate = array('<table border="1">', '</table>');
+
+ /**
+ * The HTML that will wrap around menu "row"
+ * @see setRowTemplate()
+ * @var array
+ */
+ var $_rowTemplate = array('<tr>', '</tr>');
- function startRow()
+ /**
+ * Templates for menu entries
+ * @see setEntryTemplate()
+ * @var array
+ */
+ var $_entryTemplates = array(
+ HTML_MENU_ENTRY_INACTIVE => '<td>{indent}<a href="{url}">{title}</a></td>',
+ HTML_MENU_ENTRY_ACTIVE => '<td>{indent}<b>{title}</b></td>',
+ HTML_MENU_ENTRY_ACTIVEPATH => '<td>{indent}<b><a href="{url}">{title}</a></b></td>',
+ HTML_MENU_ENTRY_PREVIOUS => '<td><a href="{url}">&lt;&lt; {title}</a></td>',
+ HTML_MENU_ENTRY_NEXT => '<td><a href="{url}">{title} &gt;&gt;</a></td>',
+ HTML_MENU_ENTRY_UPPER => '<td><a href="{url}">^ {title} ^</a></td>',
+ HTML_MENU_ENTRY_BREADCRUMB => '<td><a href="{url}">{title}</a> &gt;&gt; </td>'
+ );
+
+ function finishMenu($level)
{
- $this->_html .= '<tr>';
+ $this->_html .= $this->_menuTemplate[0] . $this->_tableHtml . $this->_menuTemplate[1];
+ $this->_tableHtml = '';
}
- function finishRow()
+ function finishRow($level)
{
- $this->_html .= '</tr>';
+ $this->_tableHtml .= $this->_rowTemplate[0] . $this->_rowHtml . $this->_rowTemplate[1];
+ $this->_rowHtml = '';
}
- function renderEntry(&$node, $level, $type)
+ function renderEntry($node, $level, $type)
{
+ $values = array($node['url'], $node['title']);
if ('tree' == $this->_menuType || 'sitemap' == $this->_menuType) {
- $indent = str_repeat('&nbsp;&nbsp;&nbsp;', $level);
+ $values[] = str_repeat('&nbsp;&nbsp;&nbsp;', $level);
} else {
- $indent = '';
- }
-
- // draw the <td></td> cell depending on the type of the menu item
- switch ($type) {
- case HTML_MENU_ENTRY_INACTIVE:
- // plain menu item
- $this->_html .= '<td>' . $indent . '<a href="' . $node['url'] . '">' .
- $node['title'] . '</a></td>';
- break;
-
- case HTML_MENU_ENTRY_ACTIVE:
- // selected (active) menu item
- $this->_html .= '<td>' . $indent . '<b>' . $node['title'] . '</b></td>';
- break;
-
- case HTML_MENU_ENTRY_ACTIVEPATH:
- // part of the path to the selected (active) menu item
- $this->_html .= '<td>' . $indent . '<b><a href="' . $node['url'] . '">' .
- $node['title'] . '</a></b></td>';
- break;
-
- case HTML_MENU_ENTRY_BREADCRUMB:
- // part of the path to the selected (active) menu item
- $this->_html .= '<td>' . $indent . '<a href="' . $node['url'] . '">' .
- $node['title'] . '</a> &gt;&gt; </td>';
- break;
-
- case HTML_MENU_ENTRY_PREVIOUS:
- // << previous url
- $this->_html .= '<td>' . $indent . '<a href="' . $node['url'] . '">&lt;&lt; ' .
- $node['title'] . '</a></td>';
- break;
-
- case HTML_MENU_ENTRY_NEXT:
- // next url >>
- $this->_html .= '<td>' . $indent . '<a href="' . $node['url'] . '">' .
- $node['title'] . ' &gt;&gt;</a></td>';
- break;
-
- case HTML_MENU_ENTRY_UPPER:
- // up url ^^
- $this->_html .= '<td>' . $indent . '<a href="' . $node['url'] . '">^ ' .
- $node['title'] . ' ^</a></td>';
- break;
+ $values[] = '';
}
+ $this->_rowHtml .= str_replace(
+ array('{url}', '{title}', '{indent}'),
+ $values,
+ $this->_entryTemplates[$type]
+ );
}
@@ -127,6 +121,56 @@ function toHtml()
{
return $this->_html;
} // end func toHtml
-}
+
+ /**
+ * Sets the menu template (HTML that wraps around rows)
+ *
+ * @access public
+ * @param string this will be prepended to the rows HTML
+ * @param string this will be appended to the rows HTML
+ */
+ function setMenuTemplate($prepend, $append)
+ {
+ $this->_menuTemplate = array($prepend, $append);
+ }
+
+
+ /**
+ * Sets the row template (HTML that wraps around entries)
+ *
+ * @access public
+ * @param string this will be prepended to the entries HTML
+ * @param string this will be appended to the entries HTML
+ */
+ function setRowTemplate($prepend, $append)
+ {
+ $this->_rowTemplate = array($prepend, $append);
+ }
+
+
+ /**
+ * Sets the template for menu entry.
+ *
+ * The template should contain at least the {title} placeholder, can also contain
+ * {url} and {indent} placeholders, depending on entry type.
+ *
+ * @access public
+ * @param mixed either type (one of HTML_MENU_ENTRY_* constants) or an array 'type' => 'template'
+ * @param string template for this entry type if $type is not an array
+ */
+ function setEntryTemplate($type, $template = null)
+ {
+ if (is_array($type)) {
+ // array_merge() will not work here: the keys are numeric
+ foreach ($type as $typeId => $typeTemplate) {
+ if (isset($this->_entryTemplates[$typeId])) {
+ $this->_entryTemplates[$typeId] = $typeTemplate;
+ }
+ }
+ } else {
+ $this->_entryTemplates[$type] = $template;
+ }
+ }
+}
?>
Oops, something went wrong.

0 comments on commit 9710b03

Please sign in to comment.