/** * Given a group of pages render a tree of navigation * * @param Page|PageArray $items Page to start the navigation tree from or pages to render * @param int $maxDepth How many levels of navigation below current should it go? * */ function renderNavTree($items, $maxDepth = 3) { // if we've been given just one item, convert it to an array of items if ($items instanceof Page) { $items = array($items); } // if there aren't any items to output, exit now if (!count($items)) { return; } // $out is where we store the markup we are creating in this function // start our <ul> markup echo "<ul class='nav nav-tree'>"; // cycle through all the items foreach ($items as $item) { // markup for the list item... // if current item is the same as the page being viewed, add a "current" class to it if ($item->id == wire('page')->id) { echo "<li class='current'>"; } else { echo "<li>"; } // markup for the link echo "<a href='{$item->url}'>{$item->title}</a>"; // if the item has children and we're allowed to output tree navigation (maxDepth) // then call this same function again for the item's children if ($item->hasChildren() && $maxDepth) { renderNavTree($item->children, $maxDepth - 1); } // close the list item echo "</li>"; } // end our <ul> markup echo "</ul>"; }
<?php // sitemap.php template file // Generate navigation that descends up to 4 levels into the tree. // See the _func.php for the renderNav() function definition. $content = renderNavTree($homepage, 4);
// render navigation to child pages renderNav($page->children); // TIP: Notice that this <div id='content'> section is // identical between home.php and basic-page.php. You may // want to move this to a separate file, like _content.php // and then include('./_content.php'); here instead, on both // the home.php and basic-page.php template files. Then when // you make yet more templates that need the same thing, you // can simply include() it from them. ?> </div><!-- end content --> <div id='sidebar'><?php // rootParent is the parent page closest to the homepage // you can think of this as the "section" that the user is in // so we'll assign it to a $section variable for clarity $section = $page->rootParent; // if there's more than 1 page in this section... if ($section->hasChildren > 1) { // output sidebar navigation // see _init.php for the renderNavTree function renderNavTree($section); } // output sidebar text if the page has it echo $page->sidebar; ?> </div><!-- end sidebar --> <?php include './_foot.php'; // include footer markup
<?php // basic-page.php template file // Primary content is the page's body copy $content = $page->body; // If the page has children, then render navigation to them under the body. // See the _func.php for the renderNav example function. if ($page->hasChildren) { $content .= renderNav($page->children); } // if the rootParent (section) page has more than 1 child, then render // section navigation in the sidebar (see _func.php for renderNavTree). if ($page->rootParent->hasChildren > 1) { $sidebar = renderNavTree($page->rootParent, 3); // make any sidebar text appear after navigation $sidebar .= $page->sidebar; }
/** * Given a group of pages, render a <ul> navigation tree * * This is here to demonstrate an example of a more intermediate level * shared function and usage is completely optional. This is very similar to * the renderNav() function above except that it can output more than one * level of navigation (recursively) and can include other fields in the output. * * @param array|PageArray $items * @param int $maxDepth How many levels of navigation below current should it go? * @param string $fieldNames Any extra field names to display (separate multiple fields with a space) * @param string $class CSS class name for containing <ul> * @return string * */ function renderNavTree($items, $maxDepth = 0, $fieldNames = '', $class = 'nav') { // if we were given a single Page rather than a group of them, we'll pretend they // gave us a group of them (a group/array of 1) if ($items instanceof Page) { $items = array($items); } // $out is where we store the markup we are creating in this function $out = ''; // cycle through all the items foreach ($items as $item) { // markup for the list item... // if current item is the same as the page being viewed, add a "current" class to it $out .= $item->id == wire('page')->id ? "<li class='current'>" : "<li>"; // markup for the link $out .= "<a href='{$item->url}'>{$item->title}</a>"; // if there are extra field names specified, render markup for each one in a <div> // having a class name the same as the field name if ($fieldNames) { foreach (explode(' ', $fieldNames) as $fieldName) { $value = $item->get($fieldName); if ($value) { $out .= " <div class='{$fieldName}'>{$value}</div>"; } } } // if the item has children and we're allowed to output tree navigation (maxDepth) // then call this same function again for the item's children if ($item->hasChildren() && $maxDepth) { if ($class == 'nav') { $class = 'nav nav-tree'; } $out .= renderNavTree($item->children, $maxDepth - 1, $fieldNames, $class); } // close the list item $out .= "</li>"; } // if output was generated above, wrap it in a <ul> if ($out) { $out = "<ul class='{$class}'>{$out}</ul>\n"; } // return the markup we generated above return $out; }
<?php include "./_head.php"; ?> <div id='content'> <?php $maxDepth = 4; renderNavTree($pages->get('/'), $maxDepth); // see the _init.php for the renderNavTree function ?> </div> <?php include "./_foot.php";