Nested Pages getCollectionName of First Parent

Permalink 6 users found helpful
I'm trying to display the name of the first parent of a page as a sub-heading. Obviously, this can be done using the getCollectionParentID function and then getting the collection name by using that ID with the Page element. The problem I'm running in to is that on a third-level nested element, the ID returned by getCollectionParentID is that of the direct parent and not the first parent.

How do I find the name of the first-level parent, which is sometimes a grandparent or great-grandparent?

Best,
Drew

 
ScottC replied on at Permalink Reply
ScottC
there is a function called getTrailToCollection or something like that, which can give you a collectionID trail back to your homepage under which every page resides.

At that point, you'd want to do an array_intersect using whatever cID you determine through api or otherwise that matches your required rules.
TheRealSean replied on at Permalink Reply
TheRealSean
I was having some trouble displaying a grandparent link when within sub pages.

But thanks to ScottC I think I have it, I don't know if this will work past level 3 which is how far I am deep

Although I assume the $_c[0] will change? unsure about this though

$c->getCollectionName(); //displays the name of the current page
$page = Page::getByID($c->getCollectionParentID());
print $page->getCollectionName(); // gets the parent name


This is the bit that displays the grandparent page name.
$nh = Loader::helper('navigation');
$_c = $nh->getTrailToCollection($c);
$page = Page::getByID($_c[0]->getCollectionParentID());
print $page->getCollectionName();
TheRealSean replied on at Permalink Reply
TheRealSean
Ok I think I have a better version

I reversed the object array so that I can grab the collection ID of the 2nd level without working backwards from our current page.

If a 2nd level does not exist we can assume we are at the current level.
<?php 
      global $c;
      $nh = Loader::helper('navigation');
      $cobj = $nh->getTrailToCollection($c);
      ?>
            <?php
         $rcobj = array_reverse($cobj);
         if(is_object($rcobj[1]))
         {
            $pID  = $rcobj[1]->getCollectionID();
            $page = Page::getByID($pID);  
            $title= $page->getCollectionName();
         }else{
            $title= $c->getCollectionName();
         }
keeasti replied on at Permalink Reply
keeasti
Thanks!
This really helped :)
cmscss replied on at Permalink Reply
Thanks for posting this - vey much appreciated.

I think I'm trying to do the same thing: always display the ultimate parent one down from the home page, no matter where you are in the tree - is that what your code does?

I've duplicated the normal atonav template (which is working great) and am now trying to integrate your code but keep getting "Catchable fatal error: Object of class Page could not be converted to string" - then gives the line number of the echo statement.

I suspect it's because I don't fully understand how to echo stuff out properly so am hoping it's a simple fix someone could help with.

Here's my template to the point I'm trying to echo the ultimate parent:
<!-- 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');
      // always display parent
      $cobj = $nh->getTrailToCollection($c);
      $rcobj = array_reverse($cobj);
         if (is_object($rcobj[1])) {
            $pID  = $rcobj[1]->getCollectionID();
            $page = Page::getByID($pID);  
            $title = $page->getCollectionName();
         }


Any help or pointers in the right direction would be much appreciated!

Cheers

Ben
msglueck replied on at Permalink Reply
msglueck
Ben, your page variable is not existing outside the scope of the if statement so no wonder you get an error. In PHP variables are scoped. So the just declaring the $page before the if statement should work.
cmscss replied on at Permalink Reply
Thank you so much for the reply - much appreciated.

I think this is way over my head as I'm used to CMS tags as found in Modx or Expression Engine.

Naively I just moved the title = out of the if statement but no joy.

Searching around, this seems to be a very common problem/request - you'd think the autonav block would have a built-in way of doing this?

Anyway, will have to put this aside for the moment as I've spent WAY to many hours trying to figure out something I thought would be fairly simple!

Cheers

Ben
cmscss replied on at Permalink Reply
For my future reference, this works!

This is the start of my autonav template which is just a straight duplication of the default autonav template (the one that creates a nested menu structure) with my ul class added as a wrapper at the top.

<!-- 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');
         // -- START Always display ultimate parent at top of NAV --
         // 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
msglueck replied on at Permalink Reply
msglueck
awesome seanom!!! I wanted to do this via recursion (getParent()...) but this is WAAAAAY better! ;) Thanks a lot!