Changing parent page with prev/next nav?

Permalink
Hi Community,

I need to add next/prev nav that will change not only pages on same level, but also will allow to change the category (parent page). This will look i.e. like that:

<< < 123 > >>

where << and >> change category (switch to next parent), and inside of them is regular next/prev nav. Can anyone help me to create the custom template (or is there other way?)?

MysteriousCleon
 
MysteriousCleon replied on at Permalink Reply
MysteriousCleon
Bump
bbeng89 replied on at Permalink Best Answer Reply
bbeng89
So your question got me kind of curious, so I decided to give it a shot. I created a custom template, but in order to get the correct functionality I had to also override the controller for the next/previous block. Anyway, here is how I did it:

Create an override directory for the next_previous block like normal by adding a folder /blocks/next_previous. In this folder create a file called controller.php.

Inside controller I just override the getNextCollection() and getPreviousCollection() methods so that they take a parameter that is the page to get the next/previous page of. By default it just always does the current page, so by adding this extra parameter we can specify the page. I also override the view() function in order to set variables containing the parents next page (parentNext) and parent's previous page (parentPrev). So this is why my controller looks like:
<?php   defined('C5_EXECUTE') or die("Access Denied."); 
class NextPreviousBlockController extends Concrete5_Controller_Block_NextPrevious { 
   function view(){
      $this->excludeSystemPages = true;
      parent::view();
      $parent = $this->get('parentCollection');
      $parentNext = $this->getNextCollection($parent);
      $parentPrev = $this->getPreviousCollection($parent);
      $this->set('parentNext', $parentNext);
      $this->set('parentPrev', $parentPrev);
   }
   function getNextCollection($p = null){
      if(empty($p)){
         $currentPage = Page::getCurrentPage();
      }


Next you need to create a template. So just make a folder /blocks/next_previous/templates then add your template file (i called mine parent_nav.php but that's not a very good name).

The template can now use the $parentNext and $parentPrev variables we set in our custom view() function. So as an example, my template looks like this (the links just display the name of the parent's next and previous pages):
<?php 
defined('C5_EXECUTE') or die("Access Denied.");
$ih = Loader::helper('image');
?>
<div id="ccm-next-previous-<?php  echo intval($bID)?>" class="ccm-next-previous-wrapper">
    <?php   if( strlen($previousLinkText) > 0){ ?>
      <div class="ccm-next-previous-previouslink">
        <?php   if( is_object($previousCollection) ){ ?>
          <a href="<?php  echo Loader::helper('navigation')->getLinkToCollection($previousCollection)?>"><?php  echo $previousLinkText ?></a>
        <?php   } else { ?>
           
        <?php   } ?>
      </div>
    <?php  } ?>
    <?php //This prints out a link to the parent's previous page ?>


Like I said, this is just the solution I came up with and there could definitely be better ways of doing it. Hopefully it helps you out though. Good luck!
MysteriousCleon replied on at Permalink Reply
MysteriousCleon
Thank you veeery much. I'll test it and then come back. I really appreciate your effort.
bbeng89 replied on at Permalink Reply
bbeng89
Hey MysteriousCleon, were you ever able to get this working?
MysteriousCleon replied on at Permalink Reply
MysteriousCleon
Yes,I've just checked it - it's brilliant. For my use I just changed order of those links becouse you gave:
prev parent_prev up parent_next next
and I need
parent_prev prev up next parent_next
but this is obviesly only cosmetics.

There is one issue though, when there is no prevoius parent (I mean in all subpages of first parent page in the sitemap) it's not looping properly - instead of showing link to last parent it gives last child of first parent. And the same situation with all children of last parent - there is no next parent, so instead of looping into first parent it loops to first child of that last parent.


If looping is off everything is ok.
bbeng89 replied on at Permalink Reply
bbeng89
Ah, I know what the issue is. At the bottom of the getNextCollection() and getPreviousCollection() you need to modify the last if statement to be:
//...in getNextCollection()
if (!is_object($page) && $this->loopSequence) {
         if(empty($p)){ //need to check the $p param
            $c = Page::getCurrentPage();
         }
         else{
            $c = $p;
         }
         $parent = Page::getByID($c->getCollectionParentID(), 'ACTIVE');
         if ($this->orderBy == 'display_asc') {
            return $parent->getFirstChild('cDisplayOrder asc', $this->excludeSystemPages);
         } else {
            return $parent->getFirstChild('cvDatePublic asc', $this->excludeSystemPages);
         }
      }


//... in getPreviousCollection()
if (!is_object($page) && $this->loopSequence) {
         if(empty($p)){ //need to check the $p param
            $c = Page::getCurrentPage();
         }
         else{
            $c = $p;
         }
         $parent = Page::getByID($c->getCollectionParentID(), 'ACTIVE');
         if ($this->orderBy == 'display_asc') {
            return $parent->getFirstChild('cDisplayOrder desc');
         } else {
            return $parent->getFirstChild('cvDatePublic desc');
         }
      }


Also I noticed that this was causing some of the system pages to show up for me (may not be an issue for you) so in my view() function i just added the line:
$this->excludeSystemPages = true;


I hope that fixes your problem!
MysteriousCleon replied on at Permalink Reply
MysteriousCleon
Exectly! Thank you. It works perfect.
bbeng89 replied on at Permalink Reply
bbeng89
Awesome! Glad you were able to get it working. I went ahead and updated the code in my original post in case anyone else stumbles across this thread.
MysteriousCleon replied on at Permalink Reply
MysteriousCleon
BTW - as you are doing this, maybe it would be good idea to improve this template by adding pagination for those child pages? I mean links to all child pages from current cathegory but with names swoped with 1 2 3 4 etc... to put in the middle of that nav. What do you think?
bbeng89 replied on at Permalink Reply
bbeng89
I'm sure it would be possible. I think you would probably achieve the pagination by using another block like the page list or autonav. Either way, I was really just trying to find a way to achieve what you were asking for in your original question out of curiosity. Unfortunately I don't personally have a use for this functionality yet, but if it ever comes up I would be glad to share my code. For now I'll leave the custom templating to you ;)
MysteriousCleon replied on at Permalink Reply
MysteriousCleon
Of course, no problem. This functionality is not necessary for me for now, but I thought that this may be good idea to have this ideas in one place. I'll try to figure this out, or maybe someone else has it alredy done...
Thank you one more time. :)
hdocwra replied on at Permalink Reply
hdocwra
-Deleted-