Wrong order after applying of pagination

Hi, I am using pagination solution from this example https://getkirby.com/docs/cookbook/navigation/pagination#range-pagination-with-a-link-for-each-page

There are two blocks, showing upcoming and current evens, and past events:

<?php
	foreach($site->find('events')->children()->filter(function($child) {
      return $child->startdate()->toDate() >= time();
})->sortBy('startdate', 'asc') as $event):
?>

<?php
	foreach($site->find('events')->children()->paginate(5)->filter(function($child) {
      return $child->startdate()->toDate() < time();
})->sortBy('startdate', 'desc') as $event):	
?>

But order is wrong after pagination, you can see dates:

Date field in “event” blueprint:

fields:
  startdate:
    label: Date
    type: date
    default: today

Also another question, I am using filter “>=”, that means — all values that are greater or equal the given value, but if I make the date TODAY, it’s not filtering, only if I make it tomorrow.

I don’t see any pagination applied here?

What do you mean? I am using this code from example https://getkirby.com/docs/cookbook/navigation/pagination#range-pagination-with-a-link-for-each-page

<ul class="pagination-list">
  <?php foreach ($list = $page->children()->paginate(5) as $item): ?>
  <li><!-- item html --></li>
  <?php endforeach ?>
</ul>

<?php $pagination = $list->pagination() ?>
<nav  class="pagination" role="navigation" aria-label="pagination">
  <ul class="pagination-list">

    <?php if ($pagination->hasPrevPage()): ?>
    <li>
      <a href="<?= $pagination->prevPageURL() ?>">‹</a>
    </li>
    <?php else: ?>
    <li>
      <span>‹</span>
    </li>
    <?php endif ?>

    <?php foreach ($pagination->range(100) as $r): ?>
    <li>
      <a class="pagination-link <?= $pagination->page() === $r ? ' is-current"' : '' ?>" href="<?= $pagination->pageURL($r) ?>">
        <?= $r ?>
      </a>
    </li>
    <?php endforeach ?>

    <?php if ($pagination->hasNextPage()): ?>
    <li>
      <a href="<?= $pagination->nextPageURL() ?>">›</a>
    </li>
    <?php else: ?>
    <li>
      <span>›</span>
    </li>
    <?php endif ?>

  </ul>
</nav>

Also strange, that on first page it’s 1 and 4 items, and on the second: 1 and 5

Are you using multiple paginations on a single page? Then see: Pagination error with 5 items, works with 10

I think it’s just one. Only there are two lists of events. But even if I leave one list of evens, same problem.

I’m a bit confused.

In the first example, you sort your pages:

<?php
	foreach($site->find('events')->children()->paginate(5)->filter(function($child) {
      return $child->startdate()->toDate() < time();
})->sortBy('startdate', 'desc') as $event):	

But then in the second

<ul class="pagination-list">
  <?php foreach ($list = $page->children()->paginate(5) as $item): ?>
  <li><!-- item html --></li>
  <?php endforeach ?>
</ul>

There is no sorting applied.

So what is your real code?

I have both codes. First is for showing events, second I took from example.

Also tried this, and got same result:

<?php
	foreach($list = $page->children()->paginate(5)->filter(function($child) {
      return $child->startdate()->toDate() < time();
})->sortBy('startdate', 'desc') as $event):	
?>
....

<?php $pages = $list->pagination() ?>
<nav  class="pagination" role="navigation" aria-label="pagination">
  <ul class="pagination-list">

    <?php if ($pages->hasPrevPage()): ?>
    <li>
      <a href="<?= $pages->prevPageURL() ?>">‹</a>
    </li>
    <?php else: ?>
    <li>
      <span>‹</span>
    </li>
    <?php endif ?>

    <?php foreach ($pages->range(4) as $r): ?>
    <li>
      <a class="pagination-link <?= $pages->page() === $r ? ' is-current"' : '' ?>" href="<?= $pages->pageURL($r) ?>">
        <?= $r ?>
      </a>
    </li>
    <?php endforeach ?>

    <?php if ($pages->hasNextPage()): ?>
    <li>
      <a href="<?= $pages->nextPageURL() ?>">›</a>
    </li>
    <?php else: ?>
    <li>
      <span>›</span>
    </li>
    <?php endif ?>

  </ul>
</nav>

Well, but your sort order doesn’t apply if you redefine your lists. It should be like this:

  1. Define your filtered list with sort order and pagination
    Do this only once and then use the variable throughout the rest of your code.
$list = $site->find('events')->children()->filter(function($child) {
      return $child->startdate()->toDate() < time();
})->sortBy('startdate', 'desc')->paginate(5);
$pagination = $list->pagination();

It probably makes sense to put this in a controller together with your other filtered list.

  1. Use the list variable in your loop
foreach($list as $item):
  // do your stuff here
endforeach
  1. The pagination using the variable defined above
<nav  class="pagination" role="navigation" aria-label="pagination">
  <ul class="pagination-list">

    <?php if ($pagination->hasPrevPage()): ?>
    <li>
      <a href="<?= $pagination->prevPageURL() ?>">‹</a>
    </li>
    <?php else: ?>
    <li>
      <span>‹</span>
    </li>
    <?php endif ?>

    <?php foreach ($pagination->range(100) as $r): ?>
    <li>
      <a class="pagination-link <?= $pagination->page() === $r ? ' is-current"' : '' ?>" href="<?= $pagination->pageURL($r) ?>">
        <?= $r ?>
      </a>
    </li>
    <?php endforeach ?>

Thank you, tried this, but now I get only one page shown in pagination. Tried to go to urls manually, like events/page:2, events/page:3, but see the same results there, for example events, that I added last, are displayed last, hovewer their date is newer than some other.

Corrected above, there was still a second paginate(5) in the list definition from copying your code above… paginate() should always be the last method in the chain.

1 Like

Also thought why it’s there :slight_smile: thank you so much, works great now! :partying_face:

To make all perfect, how can I hide pagination, if there is only one page?

Wrap the whole block in an if statement

<?php if($pagination->hasPages()): ?>
<!-- pagination nav -->
<?php endif ?>
1 Like

Great, thank you! Also tried this, to leave pagination navbar, but display page [1] as disabled:

<a <?php if (!$pages->hasNextPage()): ?>disabled<?php endif ?> class="pagination-link <?= $pages->page() === $r ? ' is-current"' : '' ?>" href="<?= $pages->pageURL($r) ?>">

Only should be <?php endif ?> at the end

Yep, of course.