Programmically creating autonav and using a 'custom' displayPages
Permalink 1 user found helpful
Thanks to the great threads at http://www.concrete5.org/community/forums/themes/perist-autonav-tem... and http://www.concrete5.org/index.php?cID=11798... I have been able to create an autonav block in a page type defaults page. I got that up and running great, but I want to expand on it a bit and display navigation for pages under a specific page with the handle 'top-navigation' instead of pulling from the root of the sitemap. However, I only want to display the navigation for that page if the Collection exists. If it doesn't I want it to pull from the root of the sitemap. The code I have is:
Just in case the page that I want to pull the navigation from gets deleted or moved around I want to get the id of it by using the handle instead of putting a static value in there. However, I noticed Collection::getByHandle()'s code creates the Collection if it doesn't exist, so if the 'top-navigation' page doesn't exist it will display a blank navigation instead of the default. I did notice in the comments for that function it states "This function is slightly misnamed: it should be getOrCreateByHandle($handle)..." so I know it is acting as expected. Would the way to do this be to copy the Collection controller over and add a function like getByHandleNoCreate(), or is there some other function I should be using for this purpose?
Thanks!
- Donald
<?php $autoNavBlock = BlockType::getByHandle('autonav'); $navPageRoot = Collection::getByHandle('top-navigation'); if(is_object($navPageRoot)) { /* Top Navigation Found */ $autoNavBlock->controller->displayPages = 'custom'; $autoNavBlock->controller->displayPagesCID = $navPageRoot->getCollectionID(); } else { /* Use root for default */ $autoNavBlock->controller->displayPages = 'top'; } $autoNavBlock->controller->orderBy = 'display_asc'; $autoNavBlock->controller->displaySubPages = 'all'; $autoNavBlock->controller->displaySubPageLevels = 'all';
Viewing 15 lines of 17 lines. View entire code block.
Just in case the page that I want to pull the navigation from gets deleted or moved around I want to get the id of it by using the handle instead of putting a static value in there. However, I noticed Collection::getByHandle()'s code creates the Collection if it doesn't exist, so if the 'top-navigation' page doesn't exist it will display a blank navigation instead of the default. I did notice in the comments for that function it states "This function is slightly misnamed: it should be getOrCreateByHandle($handle)..." so I know it is acting as expected. Would the way to do this be to copy the Collection controller over and add a function like getByHandleNoCreate(), or is there some other function I should be using for this purpose?
Thanks!
- Donald
Hey Jordanley,
Thanks for replying. I appreciate it!
I checked out the return value of getCollectionID() and it returns a value > 0 if the collection exists and isn't a page, or doesn't exist but is then created. When the call is made again with the same handle the same ID is returned. I change the handle (to one that doesn't exist) and then get another ID > 0. It looks like it does add it to the database. However, if I do request a handle that does exist but it is a page, then it doesn't return an object and thus the is_object() check must be made before using it.
I'll do some more poking around.
Thanks!
- Donald
Thanks for replying. I appreciate it!
I checked out the return value of getCollectionID() and it returns a value > 0 if the collection exists and isn't a page, or doesn't exist but is then created. When the call is made again with the same handle the same ID is returned. I change the handle (to one that doesn't exist) and then get another ID > 0. It looks like it does add it to the database. However, if I do request a handle that does exist but it is a page, then it doesn't return an object and thus the is_object() check must be made before using it.
I'll do some more poking around.
Thanks!
- Donald
Since the Collection model only returns basic collections (with no pages) and autonav is looking for a Page anyways, I thought that maybe there would be a method in the Page model. However, I looked there and only see getByID(), but nothing about doing a getByHandle(). I am still new to the api so be gentle if it's there's another obvious way.
This part of the API isn't documented, so don't feel bad :)
I think you're on the right track with using Page instead of Collection. There is a Page::getByPath method, and I have used it in code and it works -- but it takes a path to a page, not a handle, which means you need to precede the handle with a slash. For example:
$navPageRoot->cID is NULL if no page exists, or a non-zero number if the page does exist.
Of course, this only checks for the page at one location in your site -- if the page exists but is a sub-page of another page, you'd need to check for it there explicitly ( e.g. Page::getByPath('/some-page/top-navigation'); ).
Hope this works for your situation.
-Jordan
I think you're on the right track with using Page instead of Collection. There is a Page::getByPath method, and I have used it in code and it works -- but it takes a path to a page, not a handle, which means you need to precede the handle with a slash. For example:
$navPageRoot = Page::getByPath('/top-navigation'); if ($navPageRoot->cID) { /* top navigation found... */ } else { /* use root for default... */ }
$navPageRoot->cID is NULL if no page exists, or a non-zero number if the page does exist.
Of course, this only checks for the page at one location in your site -- if the page exists but is a sub-page of another page, you'd need to check for it there explicitly ( e.g. Page::getByPath('/some-page/top-navigation'); ).
Hope this works for your situation.
-Jordan
Using Page::getByPath() works out fine for my situation. Basically what I am doing is giving the person that's going to be editing the site a single location he edits items, and their order, that show up in the top navigation. I forgot though that I would get urls likehttp://www.site.com/index.php/top_navigation/page_below_top_navigat... when using this method, but it is as expected. I might go back to pulling from the root to avoid the extra addition to the path, but it's nice to have another method available.
Thanks for the help Jordan!
- Donald
Thanks for the help Jordan!
- Donald
check:
I think what those comments in the getByHandle() code mean is that an OBJECT is created, not the page itself -- but this object that's created is just an empty shell of a hypothetical page that could exist some day (maybe) -- if you check its cID, it should be 0 for these non-existent pages.