Display Top Level parent page name?
Permalink 1 user found helpful
Hi,
I have a few levels of pages, and on the lower pages (3 levels down) i would like to display their category (top level page).
Is there a way to do it? I know the below code will display the parent page name, but can it call the top level page?
<?php
$parent = Page::getByID($c->getCollectionParentID()); echo $parent->getCollectionName();
?>
Thanks in advance
I have a few levels of pages, and on the lower pages (3 levels down) i would like to display their category (top level page).
Is there a way to do it? I know the below code will display the parent page name, but can it call the top level page?
<?php
$parent = Page::getByID($c->getCollectionParentID()); echo $parent->getCollectionName();
?>
Thanks in advance
Thanks heaps for posting this example - very helpful.
I'm trying to do a similar thing and always display the ultimate parent (one down from the home page) no matter where you are in the tree - which looks like this:
Using your example code, the following displays in the sub-nav's top position:
- Store: Fatal error: Call to a member function getCollectionName()
- Bed Linen: "Home" is displayed at the top
- Sheets: "Store" is displayed at the top
- Product 1: "Bed Linen" is displayed at the top
Basically it will only display two levels up with an error when there isn't two levels up. I could hard-code "Store" at the top but then I'd have to create a sub-menu template for each section in the site.
This is what I have so far:
Sorry for not understanding - am trying to do this with little to no PHP knowledge.
Any suggestions would be welcome.
Cheers
Ben
I'm trying to do a similar thing and always display the ultimate parent (one down from the home page) no matter where you are in the tree - which looks like this:
Home |_Store |_Bed Linen |_Sheets |_Product 1 |_Product 2 |_Product 3 |_Bedspreads |_Product 1 |_Product 2 |_Product 3
Using your example code, the following displays in the sub-nav's top position:
- Store: Fatal error: Call to a member function getCollectionName()
- Bed Linen: "Home" is displayed at the top
- Sheets: "Store" is displayed at the top
- Product 1: "Bed Linen" is displayed at the top
Basically it will only display two levels up with an error when there isn't two levels up. I could hard-code "Store" at the top but then I'd have to create a sub-menu template for each section in the site.
This is what I have so far:
$parentTrail = array_reverse($nh->getTrailToCollection($c)); $objHomePage = array_pop($parentTrail); // Home page Page object $objTopPage = array_pop($parentTrail); // Current top page Page object $title = $objTopPage->getCollectionName(); $url = View::URL($objTopPage->getCollectionPath()); // print parent echo('<li><a class="current" href="' . $url . '"' . '>' . $title . '</a>' . '</li>');
Sorry for not understanding - am trying to do this with little to no PHP knowledge.
Any suggestions would be welcome.
Cheers
Ben
I've modified the original code since I realized it had a small flaw.
For your situation I guess this is close to what you're asking about:
Are you just trying to hard-code a link to the current path's main parent on each page?
For your situation I guess this is close to what you're asking about:
$c = Page::getCurrentPage(); // If not on the home page if($c->cID > 1){ $nh = Loader::helper('navigation'); $arrTrail = array_reverse($nh->getTrailToCollection($c)); $objHomePage = $arrTrail[0]; // Home page object; // If we're on a top-level page then our $arrTrail array will only have the home page object // so we test to see if its Page object exists $objTopPage = is_object($arrTrail[1]) && $arrTrail[1] instanceof Page && !$arrTrail[1]->error ? $arrTrail[1] : NULL; // If we have a valid top page Page object we retrieve $title = $objTopPage ? $objTopPage->getCollectionName() : ''; $url = $objTopPage ? $nh->getLinkToCollection($objTopPage) : ''; }
Are you just trying to hard-code a link to the current path's main parent on each page?
Mate, thank you so much for replying.
I get the following error:
"Catchable fatal error: Object of class Page could not be converted to string" then it gives me the line number of the echo statement.
I think my syntax is a bit screwy - is the generic autonav template code beforehand conflicting with your suggestion or is it my echo statement?
I don't know any php sorry but hope this is basic to fix!
No worries if it's too hard.
Cheers
Ben
I get the following error:
"Catchable fatal error: Object of class Page could not be converted to string" then it gives me the line number of the echo statement.
I think my syntax is a bit screwy - is the generic autonav template code beforehand conflicting with your suggestion or is it my echo statement?
<!-- sub navigation --> <ul class="s-nav"> <?php defined('C5_EXECUTE') or die("Access Denied."); $aBlocks = $controller->generateNav(); $c = Page::getCurrentPage(); $containsPages = false; $nh = Loader::helper('navigation'); // If not on the home page if($c->cID > 1){ $nh = Loader::helper('navigation'); $arrTrail = array_reverse($nh->getTrailToCollection($c)); $objHomePage = $arrTrail[0]; // Home page object; // If we're on a top-level page then our $arrTrail array will only have the home page object // so we test to see if its Page object exists $objTopPage = is_object($arrTrail[1]) && $arrTrail[1] instanceof Page && !$arrTrail[1]->error ? $arrTrail[1] : NULL;
Viewing 15 lines of 21 lines. View entire code block.
I don't know any php sorry but hope this is basic to fix!
No worries if it's too hard.
Cheers
Ben
If we're not below one the main parent pages (a page directly under the home page) then that $nh->getTrailToCollection() function will only return the Page object (a.k.a. page information) for the home page.
We need to test to make sure we are on a sub page of the main parent page so we don't attempt to request information about an object that doesn't exist.
So that line in question is basically saying:
If the Page object (page information about the current main parent page) does NOT exist, then don't echo out a link to it since we're most likely already viewing it.
If the Page object DOES exist, then it means we're on one of its sub pages so we can safely request information from it (its name, link, etc.).
Hope that helps :)
We need to test to make sure we are on a sub page of the main parent page so we don't attempt to request information about an object that doesn't exist.
So that line in question is basically saying:
If the Page object (page information about the current main parent page) does NOT exist, then don't echo out a link to it since we're most likely already viewing it.
If the Page object DOES exist, then it means we're on one of its sub pages so we can safely request information from it (its name, link, etc.).
Hope that helps :)
OK, I'm beginning to understand - thanks for that, much appreciated.
So if I wanted to have the ultimate parent display in the menu when actually on the ultimate parent page (just for consistency - I would do something like this in an else statement?
As you can see, I'm just copying and modifying code that worked previously - which doesn't work!
Have you already defined the ultimate parent as a variable in your code which I could reuse in my else statement - or is what I've done the right idea, just the wrong execution?
Have also tried this for the else statement:
So if I wanted to have the ultimate parent display in the menu when actually on the ultimate parent page (just for consistency - I would do something like this in an else statement?
<!-- sub navigation --> <ul class="s-nav"> <?php defined('C5_EXECUTE') or die("Access Denied."); $aBlocks = $controller->generateNav(); $c = Page::getCurrentPage(); $containsPages = false; $nh = Loader::helper('navigation'); // If not on the home page if ($c->cID > 1) { $nh = Loader::helper('navigation'); $arrTrail = array_reverse($nh->getTrailToCollection($c)); $objHomePage = $arrTrail[0]; // Home page object; // If we're on a top-level page then our $arrTrail array will only have the home page object // so we test to see if its Page object exists $objTopPage = is_object($arrTrail[1]) && $arrTrail[1] instanceof Page && !$arrTrail[1]->error ? $arrTrail[1] : NULL;
Viewing 15 lines of 29 lines. View entire code block.
As you can see, I'm just copying and modifying code that worked previously - which doesn't work!
Have you already defined the ultimate parent as a variable in your code which I could reuse in my else statement - or is what I've done the right idea, just the wrong execution?
Have also tried this for the else statement:
// If on the ultimate parent else { $title = getCollectionName(); $url = getCollectionPath(); // print parent (if on the ultimate parent) echo '<li><a class="current" href="' . $url . '"' . '>' . $title . '</a>' . '</li>';
Replace this IF statement
with this:
Now, we're saying that if we're not a sub page of the parent then we must be on the parent itself so we'll use whichever to get the name and URL so we can always show a link.
Let me know how that works out.
if($c->cID > 1){ // blah blah blah }
with this:
// If not on the home page if ($c->cID > 1) { $nh = Loader::helper('navigation'); $arrTrail = array_reverse($nh->getTrailToCollection($c)); $objHomePage = $arrTrail[0]; // Home page object; // If we're on a top-level page then our $arrTrail array will only have the home page object // so we test to see if its Page object exists $objTopPage = is_object($arrTrail[1]) && $arrTrail[1] instanceof Page && !$arrTrail[1]->error ? $arrTrail[1] : $c; // If we have a valid top page Page object we retrieve $title = $objTopPage->getCollectionName(); $url = $nh->getLinkToCollection($objTopPage); // print parent (if on one of its subpages) echo '<li><a class="current" href="' . $url . '"' . '>' . $title . '</a>' . '</li>'; }
Now, we're saying that if we're not a sub page of the parent then we must be on the parent itself so we'll use whichever to get the name and URL so we can always show a link.
Let me know how that works out.
Mate - totally awesome!
So an important thing that has changed is that we're no longer checking for NULL here:
We have $c instead - is this the concrete5 class?
Sorry to bug you - it works great so only answer if you have time.
Cheers
Ben
So an important thing that has changed is that we're no longer checking for NULL here:
$arrTrail[1]->error ? $arrTrail[1] : NULL;
We have $c instead - is this the concrete5 class?
$arrTrail[1]->error ? $arrTrail[1] : $c;
Sorry to bug you - it works great so only answer if you have time.
Cheers
Ben
Glad to hear it's working - and don't worry about asking a lot of questions; it's good practice for me :)
$c is the current page's Page object which we retrieved by doing:
It acts as a starting point to building the breadcrumb list when we call $nh->getTrailToCollection($c).
$c is the current page's Page object which we retrieved by doing:
$c = Page:getCurrentPage();
It acts as a starting point to building the breadcrumb list when we call $nh->getTrailToCollection($c).
I think I'm understanding about 12% of what you're tailing about!
Got it - we're defining $c further up as you say.
Do you do consulting or are you employed?
Got it - we're defining $c further up as you say.
Do you do consulting or are you employed?
Employed - hope my boss doesn't read this :)
Diving into editing concrete5's blocks can be pretty daunting especially if you don't have a basic grasp of PHP and the guts of the CMS itself.
Kudos for trying :)
Diving into editing concrete5's blocks can be pretty daunting especially if you don't have a basic grasp of PHP and the guts of the CMS itself.
Kudos for trying :)
Thanks mate - much appreciated!
This is something that worked for me if someone wanted to put it into the page template, and not into an autonav.
Basically, in your theme, it will check if its the homepage, and also check if its a top level navigation page. If it is, it displays the title. If its a 2nd level navigation page, it displays the parent title.
It works in a situation like this:
Home
About
Products
-Subcategory 1
-Subcategory 2
Where as the subcategory page will still display "Products" as the main title, then you can echo out the current page name as a subtitle.
<h1><?php $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 $parent->getCollectionName(); } ?> </h1>
Basically, in your theme, it will check if its the homepage, and also check if its a top level navigation page. If it is, it displays the title. If its a 2nd level navigation page, it displays the parent title.
It works in a situation like this:
Home
About
Products
-Subcategory 1
-Subcategory 2
Where as the subcategory page will still display "Products" as the main title, then you can echo out the current page name as a subtitle.
You can also parse out the first tier from $_SERVER['REQUEST_URI'] and do a Page::getByPath('path here'), but the first solution will ensure it will run successfully even if you're viewing the default for a page type through the dashboard (without any additional checks).