Pagination problem with Parameters

Hi Kirby folks,

I’m working on creating a calendar section of a website, I’ve gotten pagination working, and even figured out how to filter by year of the event. I wanted to create some additional filters - for date spans, and was able to do so by appending the url and then matching an if statement to that. The problem comes when I try to paginate those pages.

Here is my current pagination setup:

<?php if($articles->pagination()->hasPages()): ?>

		<nav>
			<h5>
  			<?php if($pagination->hasPrevPage()): ?>
    		<a href="<?php echo $pagination->prevPageURL() ?>">&larr; newer</a>&nbsp;|&nbsp;&nbsp;
    		<?php endif ?>

    		<?php foreach($pagination->range() as $r): ?>
    		<a<?php if($pagination->page() == $r) echo ' class="magenta"' ?> href="<?php echo $pagination->pageURL($r) ?>"><?php echo $r ?></a>
    		<?php endforeach ?>

    		<?php if($pagination->hasNextPage()): ?>
    		&nbsp;&nbsp;|&nbsp;<a href="<?php echo $pagination->nextPageURL() ?>">earlier &rarr;</a>
    		<?php endif ?>
  			</h5>
		</nav>

<?php endif ?>

Which I believe is pretty standard, and works just great.

Here is the controller:

<?php

return function($site, $pages, $page) {

  // get the events that are not part of the 'upcoming' feature snippet
  $past = $page->children()->visible()->flip()->filterBy('date', '<', time());
  $future = $page->children()->visible()->flip()->filterBy('date', '>', strtotime("+30 days"));
  $articles = $past;
  $recent = $page->children()->visible()->flip()->filterBy('date', '>', strtotime("2009-12-31"));
  $urlactive = (kirby()->request()->url());
  
  // pass results to the template
  function calYear($recent) {
  return $recent->date('Y'); // year, e.g. "2016"
  }
  
  // allow filtering to the URL
  if($year = param('year')) {
  $articles = $past->filter(function($p) use($year) {
    	return $p->date('Y') === $year;
  		});
  }

  // create young span filter - 2005-09
  $url_young = (page('calendar')->url() . '/span:young');
  
  if($urlactive == $url_young) {
	$articles = $page->children()->visible()->flip()->filterBy('date', '>', strtotime("2004-12-31"))->filterBy('date', '<', strtotime("2010-01-01"));
	}
  
  
  // create early span filter - Pre 2005
  $url_early = (page('calendar')->url() . '/span:early');
  
  if($urlactive == $url_early) {
	$articles = $page->children()->visible()->flip()->filterBy('date', '<', strtotime("2005-01-01"));
	}
  
  // pagination
  $articles = $articles->paginate(14);
  $pagination = $articles->pagination();
  
  // Counters 
  $futureyes = $future->count();
  
  // pass results to the template
  return compact('articles', 'future', 'recent', 'futureyes', 'pagination', 'urlactive');

};

And here is the filtering interface that creates the URLs:

		<?php
    		$urllinked = (page('calendar')->url());
    		if ($urlactive != $urllinked): ?>
    		<h2 class="dark"><?php endif; ?>
		<?php
    		$urllinked = (page('calendar')->url());
    		if ($urlactive == $urllinked): ?>
    		<h2><?php endif; ?>
		<a href="<?= page('calendar')->url() ?>">ALL</a></h2>
		<?php foreach ($recent->group('calYear') as $year => $yearList): ?>
  		<?php
    		$urllinked = (page('calendar')->url() . '/year:' . $year);
    		if ($urlactive != $urllinked): ?>
    		<h2 class="dark"><?php endif; ?>
    		<?php
    		$urllinked = (page('calendar')->url() . '/year:' . $year);
    		if ($urlactive == $urllinked): ?>
    		<h2><?php endif; ?>
    		<a href="<?= page('calendar')->url() . '/year:' . $year ?>"><?php echo $year ?></a></h2>	
	<?php endforeach ?>
	<?php
    	$urllinked = (page('calendar')->url() . '/span:young');
    	if ($urlactive != $urllinked): ?>
    	<h2 class="dark"><?php endif; ?>
	<?php
    	$urllinked = (page('calendar')->url() . '/span:young');
    	if ($urlactive == $urllinked): ?>
    	<h2><?php endif; ?>
    	<a href="<?= page('calendar')->url() ?>/span:young">2005-2009</a></h2>
	<?php
    	$urllinked = (page('calendar')->url() . '/span:early');
    	if ($urlactive != $urllinked): ?>
    	<h2 class="dark"><?php endif; ?>
	<?php
    	$urllinked = (page('calendar')->url() . '/span:early');
   	if ($urlactive == $urllinked): ?>
   	<h2><?php endif; ?>
   	<a href="<?= page('calendar')->url() ?>/span:early">Early</a></h2>

I tried changing the url generated to be span_young or span_early but then it no longer works. My guess is this is some sort of problem with the use of a param() that is not properly defined, but I’m not sure how to fix that with this.

If I decrease the pagination from 14 to, say 4, the pagination works correctly on the filtered content that uses the dynamically created param() but where I sort of fake the param it seems to not work. The page is live here: http://data.randy-gibson.com/calendar

Thanks so much for any input and advice!!

I think the reason why it does not work as expected is that you use the URL as a basis for your filtering instead of the param. You can use the param for the span as well:

if($span = param('span') && $span == "young" ) {
  $articles = $page->children()->visible()->flip()->filterBy('date', '>', strtotime("2004-12-31"))->filterBy('date', '<', strtotime("2010-01-01"));
}

if($span = param('span') && $span == "early" ) {
	$articles = $page->children()->visible()->flip()->filterBy('date', '<', strtotime("2005-01-01"));
}

Apart from that, your if statements in the last code block are a bit strangely set.

Amazing Sonja,

I had to declare the span param separately, but it’s working perfectly now. ultimately this is the code that worked (in the controller):

$span = param('span');

// create young span filter - 2005-09
  	if($span == "young") {
	$articles = $page->children()->visible()->flip()->filterBy('date', '>', strtotime("2004-12-31"))->filterBy('date', '<', strtotime("2010-01-01"));
	}

And yeah, the if statements are a bit odd, but so far that’s been the most elegant solution I’ve found.

Thanks again!!