Is there a better way to do this?
Permalink
I'm always struggling with finding a way to get sub-pages to display a sidebar nav that shows ALL pages underneath the current top-level page.
I came up with this:
This basically is checking for a current page, parent page and grandparent page and seeing if those pages have children. If certain criteria are met, the nav controller is adjusted accordingly to always make sure I'm display all pages underneath the top-level parent page.
This only works down to three levels deep though (the grandparent page check).
Is there an easier way to do this?
Thanks!
I came up with this:
$current = Page::getCurrentPage(); $parent = Page::getByID($c->getCollectionParentID()); $grandParent = Page::getByID($parent->getCollectionParentID()); if(($current->getNumChildren() > 0 && $current->getCollectionName() != 'Home') || ($parent->getCollectionName() != 'Home' && $parent->getNumChildren() > 0 )) { $navBT = BlockType::getByHandle('autonav'); if($parent->getCollectionName() == 'Home' && $current->getNumChildren() > 0) { $navBT->controller->displayPages = 'below'; echo '<h2>' . $current->getCollectionName() . '</h2>'; } elseif($grandParent->getCollectionName()!= 'Home' && $parent->getNumChildren() > 0) { $navBT->controller->displayPages = 'above'; echo '<h2>' . $grandParent->getCollectionName() . '</h2>'; } elseif($parent->getCollectionName()!= 'Home' && $parent->getNumChildren() > 0) {
Viewing 15 lines of 23 lines. View entire code block.
This basically is checking for a current page, parent page and grandparent page and seeing if those pages have children. If certain criteria are met, the nav controller is adjusted accordingly to always make sure I'm display all pages underneath the top-level parent page.
This only works down to three levels deep though (the grandparent page check).
Is there an easier way to do this?
Thanks!
wow, both of you went over kill ;)
<?php Loader::block('autonav'); $nh = Loader::helper('navigation'); $page = Page::getByPath("/some/page"); //$page = Page::getByID(HOME_CID); $nav = AutonavBlockController::getChildPages($page); foreach($nav as $n2) { $cp = new Permissions($n2); if ($cp->canRead()) { ?> <li><a href="<?=$nh->getLinkToCollection($n2, false, true)?>"><?=t($n2->getCollectionName())?></a></li> <? }
That works but only under the page you specify.
What I want is a dynamic nav that works regardless of where in the site the user is currently at.
And also, your method doesn't add nested ULs for sub menus, nor does it do all the "Extras" that my AutoNav template does by adding custom css classes to each nav item for styling.
What I want is a dynamic nav that works regardless of where in the site the user is currently at.
And also, your method doesn't add nested ULs for sub menus, nor does it do all the "Extras" that my AutoNav template does by adding custom css classes to each nav item for styling.
ok. thats easy,
<?php Loader::block('autonav'); $nh = Loader::helper('navigation'); $page = Page::getCurrentPage(); $nav = AutonavBlockController::getChildPages($page); foreach($nav as $n2) { $cp = new Permissions($n2); if ($cp->canRead()) { ?> <li><a href="<?=$nh->getLinkToCollection($n2, false, true)?>"><?=t($n2->getCollectionName())?></a></li> <? }
And will that output all pages under the current given top-level section or just the Child Pages under the current page?
that just does the immediate children
That's what I thought.
See...not as simple as you suspected! ;-)
See...not as simple as you suspected! ;-)
I though thats what you wanted, if you want it recursive just use the autonav block...
I've tried the autonav block and it still doesn't work like I want it to. It doesn't seem to have a setting to display all pages underneath the current top-level path.
Every setting I've found in the autonav just displays the pages underneath the current page, and then clicking on one of the sibling pages no longer shows the rest of the sibling pages.
Every setting I've found in the autonav just displays the pages underneath the current page, and then clicking on one of the sibling pages no longer shows the rest of the sibling pages.
Can you draw out some kind of tree structure what you exactly want? I'm not quite getting it...
Like this kind of explanation:
main 1
main 2
-main2 sub1
-main2 sub2
--main2 sub2 sub 1
--main2 sub2 sub 2
main 3
Like this kind of explanation:
main 1
main 2
-main2 sub1
-main2 sub2
--main2 sub2 sub 1
--main2 sub2 sub 2
main 3
Okay...let's say my site structure looks like this:
Home
-Sub 1
--Sub 1.1
--Sub 1.2
--Sub 1.3
-Sub 2
-Sub 3
--Sub 3.1
--Sub 3.2
---Sub 3.2.1
---Sub 3.2.2
---Sub 3.2.3
--Sub 3.2
-Sub 4
And let's say the user is on page Sub 3.2.3
I went my sidebar menu on every page under Sub 3 to display this:
<h2>Sub 3</h2>
--Sub 3.1
--Sub 3.2
---Sub 3.2.1
---Sub 3.2.2
---Sub 3.2.3
--Sub 3.2
But it should by dynamic enough to always pull in the top level parent name for the title and display children as many levels deep as I have in the sitemap, regardless of how deep the user is in the page structure.
Home
-Sub 1
--Sub 1.1
--Sub 1.2
--Sub 1.3
-Sub 2
-Sub 3
--Sub 3.1
--Sub 3.2
---Sub 3.2.1
---Sub 3.2.2
---Sub 3.2.3
--Sub 3.2
-Sub 4
And let's say the user is on page Sub 3.2.3
I went my sidebar menu on every page under Sub 3 to display this:
<h2>Sub 3</h2>
--Sub 3.1
--Sub 3.2
---Sub 3.2.1
---Sub 3.2.2
---Sub 3.2.3
--Sub 3.2
But it should by dynamic enough to always pull in the top level parent name for the title and display children as many levels deep as I have in the sitemap, regardless of how deep the user is in the page structure.
Hi,
I think this can be achieved by adding few lines in my first example:
I also tested that now so it should do what you want to. Please also note that you can/should set the $level variable there as you wish.
Br,
Antti / Mainio
I think this can be achieved by adding few lines in my first example:
// Set your level here // 0 = the first level after home page level (home => CHILD) // 1 = the second level (home => child => CHILD) // etc. $level = 0; $current = $p = Page::getCurrentPage(); $tree = array(); while ($p->getCollectionParentID() >= HOME_CID) { array_push($tree, $p); $p = Page::getByID($p->getCollectionParentID()); } $tree = array_reverse($tree); if (isset($tree[$level])) { $parent = $tree[$level]; echo '<h2>' . $parent->getCollectionName() . '</h2>';
Viewing 15 lines of 23 lines. View entire code block.
I also tested that now so it should do what you want to. Please also note that you can/should set the $level variable there as you wish.
Br,
Antti / Mainio
Mainio,
This seems to do exactly what I need it to do! I haven't tested fully, but so far it works great.
THANK YOU!
This seems to do exactly what I need it to do! I haven't tested fully, but so far it works great.
THANK YOU!
At least I usually try to use the MVC structure built in and avoid custom printing out. This way I can take advantage of the c5 templates already included in the block folder. So you kinda "need to" overkill this one to use the block as it would be used when a new block is created.
Also, I don't really like that there's still A LOT of stuff in C5 that says e.g. echo '<table><tr><td>' etc. I know it's quite many times faster to do that and I also know that the autonav block's templates do this, but my personal opinion is that if you have HTML inside echo, it's not correct.
EDIT: This was @Mnkras comment on the overkilling, I think I clicked the reply button at the wrong place.
Also, I don't really like that there's still A LOT of stuff in C5 that says e.g. echo '<table><tr><td>' etc. I know it's quite many times faster to do that and I also know that the autonav block's templates do this, but my personal opinion is that if you have HTML inside echo, it's not correct.
EDIT: This was @Mnkras comment on the overkilling, I think I clicked the reply button at the wrong place.
This would find the level X parent page (counting from bottom up, meaning that pages below the home page are at the very bottom).
Now sure though if it:
- Prints out the correct title that you want to
- Really works, just copied your code and modified it in notepad (has not been tested in any way!!!)
- Works as you intended it to
However, my point posting this is that you would get further from here by yourself. The key here is setting the $navBT->controller->displayPages to 'custom', so that you can control from which collection it takes the subpages with the displayPagesCID variable.
Br,
Antti / Mainio