Neo Posted June 3, 2015 Share Posted June 3, 2015 I basically just got started with ProcessWire, followed the beginners tutorials and just try to implement a test site using the beginners template. My PHP knowledge is limited, so please bear with me. What I am trying to achieve is implement a second level for the menu resembling the following html structure: <ul class="menu" id="responsive"> <li><a href="index.html" id="current"> Home</a></li> <li><a href="about.html"> About</a> <li><a href="#"> Services</a> <!-- Second Level / Start --> <ul> <li><a href="service1.html">Service 1</a></li> <li><a href="service2.html">Service 2</a></li> <li><a href="service3.html">Service 3</a></li> <li><a href="service4.html">Service 4</a></li> </ul> <!-- Second Level / End --> </li> <li><a href="#"> Portfolio</a> </ul> Following the example in the beginners template, I managed to get the first level going: <ul class="menu" id="responsive"><?php // top navigation consists of homepage and its visible children $homepage = $pages->get('/'); $children = $homepage->children(); // make 'home' the first item in the navigation $children->prepend($homepage); // render an <li> for each top navigation item foreach($children as $child) { if($child->id == $page->rootParent->id) { // this $child page is currently being viewed (or one of it's children/descendents) // so we highlight it as the current page in the navigation echo "<li><a href='$child->url' id='current'>$child->title</a></li>"; } else { echo "<li><a href='$child->url'>$child->title</a></li>"; } } ?></ul> However, I am struggeling with the the second-level. Would appreciate your guidance. Link to comment Share on other sites More sharing options...
Ivan Gretsky Posted June 4, 2015 Share Posted June 4, 2015 If you do not insist on doing it all by yourself, you could just use this usefull module for building menus. 2 Link to comment Share on other sites More sharing options...
Christophe Posted June 4, 2015 Share Posted June 4, 2015 Here is the code I use for at least one website for the moment. I don't remember exactly where in the forum(s) or in which profile I found it. I don't remember if it was one, or if I merged two pieces of code (perhaps I added the first "<li>"). It could be a start. (I'm also a php beginner.) <!-- Horizontal Menu --> <ul class="menu"><li><a href="<?=$config->urls->root?>"><?=$pages->get('/')->title?></a></li><?php function topMenu($currentPage, $startPage) { $out = ''; foreach($startPage->children as $page) { $class = ''; if($currentPage->id == $page->id) $class = " class='current'"; $out .= "<li$class><a href='$page->url'>$page->title</a>"; if(count($page->children)) { $out .= "<ul>" . topMenu($currentPage, $page, $level+1) . "</ul>"; } $out .= "</li>"; } return $out; } echo topMenu($page, $pages->get('/')); ?></ul> Link to comment Share on other sites More sharing options...
Neo Posted June 4, 2015 Author Share Posted June 4, 2015 I finally ended up using the recommended Markup Simple Navigation module, which is probably the cleanest and most customizable solution without reinventing the wheel. Thanks a lot. Link to comment Share on other sites More sharing options...
diogo Posted June 5, 2015 Share Posted June 5, 2015 It's not good to reinvent the wheel, but it's not bad to know how wheels are made. What you want to do is actually quite simple, and all you need is a loop inside the first loop. For only two levels, a very simplified version could look like this: echo "<ul>"; foreach($homepage->children as $item) { // loop through the children of root echo "<li><a href='$item->url'>$item->title</a>"; if ($item->numChildren(true)) { // check if this item has children echo "<ul>"; foreach($item->children as $sub_item) { // loop through the children of each item echo "<li><a href='$sub-item->url'>$sub_item->title</a></li>"; } echo "</ul>"; } echo "</li>"; } echo "</ul>"; For more levels, you could keep adding loops inside loops, but then, it would make more sense to make a recursive function (a function that calls itself while there still are children). One more thing. In your code you add the id for the current page like this: if($child->id == $page->rootParent->id) { // this $child page is currently being viewed (or one of it's children/descendents) // so we highlight it as the current page in the navigation echo "<li><a href='$child->url' id='current'>$child->title</a></li>"; } else { echo "<li><a href='$child->url'>$child->title</a></li>"; } You can avoid repeating code by doing this instead: if($child->id == $page->rootParent->id) { $current = ' class="current"'; } else { $current = ''; } echo "<li><a href='$child->url'{$current}'>$child->title</a></li>"; Or, more compact: $current = $child->id == $page->rootParent->id ? ' class="current"' : ''; echo "<li><a href='$child->url'{$current}'>$child->title</a></li>"; You can also replace $child->id == $page->rootParent->id by $item == $page for the current page and use rootParent to give the class to the parent item only 3 Link to comment Share on other sites More sharing options...
Neo Posted June 5, 2015 Author Share Posted June 5, 2015 Great. Thanks for your detailed solution and explanations. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now