julian Posted November 26, 2011 Posted November 26, 2011 In advance, I did search and found nothing that helped, including the thread discussing the "treeMenu" function, which doesn't do what I want (at least not quite). What I'm after is a really simple, static navigation with the following structure, visible on every page: <ul id="menu"> <li>item 1</li> <li>item 2 <ul> <li>item 2a</li> <li>item 2b</li> </ul> </li> <li>item 3 <ul> <li>item 3a</li> <li>item 3b</li> <li>item 3c</li> </ul> </li> </ul> In the past, and with every other CMS I've tried out, this has always been a doddle, and I picked ProcessWire today because I though it looked nice, clean and simple; the 30 odd lines of code in the other thread which talk about achieving something similar to this is NOT what I would consider to be simple (no offence intended). Is there no other way around this? Surely this is really basic stuff?... I'm not a programmer, but I imagine it could work something like "for each links as link, if link has children show them to n level..."?
julian Posted November 26, 2011 Author Posted November 26, 2011 Oh I'm such a cock. Can just use site map. Sorry.
julian Posted November 27, 2011 Author Posted November 27, 2011 I still can't get it to work, for some reason all the pages are children of "home", rather than all being a root page. Is there no way to get a dropdown menu to work?
ryan Posted November 27, 2011 Posted November 27, 2011 I'm thinking you want something like this? <?php function listChildrenTree($children) { echo "<ul>"; foreach($children as $page) { echo "<li><a href='{$page->url}'>{$page->title}</a> "; if($page->numChildren) listChildrenTree($page->children); echo "</li>"; } echo "</ul>"; } listChildrenTree($pages->get('/')->children); That would do something similar to the sitemap, but has the first level of pages as root leaves rather than the homepage.
thetuningspoon Posted March 2, 2012 Posted March 2, 2012 I need to accomplish the same thing as Julian, but with the Home page tacked onto it (with an image inside the <li>, which you helped me out with before). I tried figuring this out on my own (I really did!): function listChildrenTree($children) { echo "<ul>"; foreach($children as $page) { echo "<li><a href='{$page->url}'>"; if($page->id == $pages->get("/")->id) echo "<img src='" . $config->urls->templates . "styles/images/home.png' width='24' height='28' alt='' />"; echo "{$page->title}</a> "; if($page->numChildren) listChildrenTree($page->children); echo "</li>"; } echo "</ul>"; } $homepage = $pages->get("/"); $children = $homepage->children("limit=6"); $children->prepend($homepage); listChildrenTree($children); But it seems to be choking whenever I try to use $pages or $config inside of the function. Is it not possible to access the API variables from within a function? If so, what's the best practice here? I must be missing something obvious!
apeisa Posted March 2, 2012 Posted March 2, 2012 You have two options inside function: wire('pages'); wire('config'); wire('page'); or then passing needed variables as function params: renderSubmenu($page); function renderSubmenu($page) { ... }
thetuningspoon Posted March 2, 2012 Posted March 2, 2012 Thanks, apeisa. I can't seem to get it to work in my example. Can you show me more specifically how this would be implemented? for example, to get the id of the home page: $pages->get("/")->id How would I write this in a function? Wrap the whole thing?
thetuningspoon Posted March 2, 2012 Posted March 2, 2012 Thanks. I was just looking at the Include & Bootstrap portion of the documentation. Is $wire->$pages->get("/")->id also an option? Seems a bit simpler to me. Neither of them seem to be working for me at the moment, but I'll keep working on it.
apeisa Posted March 2, 2012 Posted March 2, 2012 Include & Bootstrap is when you have whole PW included or you run it from shell script or something like that. wire('pages')->get('/')->id should work everywhere and return 1.
thetuningspoon Posted March 2, 2012 Posted March 2, 2012 Got it, thanks. Is this in the documentation? Seems like something that should be a bit more visible. Got it working along with an "on" class for the active page: function listChildrenTree($children) { echo "<ul>"; foreach($children as $page) { $class = $page->id == wire('page')->rootParent->id ? " class='on'" : ''; echo "<li><a href='{$page->url}' $class>"; if($page->id == wire('pages')->get("/")->id) echo "<img src='" . wire('config')->urls->templates . "styles/images/home.png' width='24' height='28' alt='' />"; echo "{$page->title}</a> "; if($page->numChildren && $page->id != wire('pages')->get("/")->id) listChildrenTree($page->children); echo "</li>"; } echo "</ul>"; } $children = $pages->get("/")->children(); $children->prepend($pages->get("/")); listChildrenTree($children); I tried passing the home page to the function as a parameter and using that instead of wire('pages')->get("/")->id but any time I tried to add a second parameter to the function the script errored. Any idea why this would be?
Soma Posted March 2, 2012 Posted March 2, 2012 function listChildrenTree($children, $current, $w) { echo "<ul>"; foreach($children as $page) { $class = ''; if($page === $current || $current->parents->slice(1)->has($page) ) { $class = "class='on' style='font-weight:bold'"; } $rootid = $w->pages->get("/")->id; echo "<li><a href='{$page->url}' $class>"; if($page->id == $rootid) echo "<img src='" . $w->config->urls->templates . "styles/images/home.png' width='24' height='28' alt='' />"; echo "{$page->title}</a> "; if($page->numChildren && $page->id != $rootid) listChildrenTree($page->children, $current, $w); echo "</li>"; } echo "</ul>"; } $children = $pages->get("/")->children(); $children->prepend($pages->get("/")); listChildrenTree($children, $page, $wire); 2
mike77 Posted October 25, 2012 Posted October 25, 2012 I have a question concering the code beneath: <?php function listChildrenTree($children) { echo "<ul>"; foreach($children as $page) { echo "<li><a href='{$page->url}'>{$page->title}</a> "; if($page->numChildren) listChildrenTree($page->children); echo "</li>"; } echo "</ul>"; } listChildrenTree($pages->get('/')->children); It works fine (it skips the root page which is logical and natural way of putting navigation) but I need to add a class to the children's children (grand-children of the root) items of the navigation so I could hide them with css/jquery (and show on mouse hover). How do I do this? I tried few modifications but I faced the problem of identifying the grand-children out of the script loop flow. Anyone? Thanks.
Soma Posted October 25, 2012 Posted October 25, 2012 You could use my MarkupSimplaNavigation module to generate the navigation. I think you don't need to add classes to first grandchildren, as you could target them by CSS and JS easily without.
mike77 Posted October 25, 2012 Posted October 25, 2012 Thanks Soma. Your module looks great. I will check it out tomorrow. Thanks again for the feedback! Edit: yes it all went perfect. With nested classes the module allows to easly style the grandchildren in css and make them behave in JS. Thanks again.
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