Kirby code Error in "$pagination->range()"

To document the error in a comprehensible way:

  • Install Kirby Starterkit 3.4.2
  • Enter additional 13 “note” pages, so that at least 20 “note” pages are visible as links on the original “notes” page in the frontend.
  • Then change the “notes” template to
<?php // file: site/templates/notes.php
      // changes like: https://getkirby.com/docs/cookbook/templating/pagination#range-pagination-with-a-link-for-each-page
?>

<?php snippet('header') ?>

<main>
  <?php snippet('intro') ?>

<?php $mypaginate = 2; // we néed many pagination links ?>

  <div class="notes">
    <?php foreach ($notes = $page->children()->listed()->sortBy('date', 'desc')->paginate($mypaginate) as $note): ?>
    <article class="note">
      <header class="note-header">
        <a href="<?= $note->url() ?>">
          <h2><?= $note->title() ?></h2>
          <time><?= $note->date()->toDate('d F Y') ?></time>
          <p><i>Page #<?= $page->children()->count() - $note->indexOf() ?></i></p>
        </a>
      </header>
    </article>
    <?php endforeach ?>
  </div>

<?php $myrange = 5; ?>
<?php $pagination = $notes->pagination() ?>

  <br><br>
  <nav class="social">

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

    <?php foreach ($pagination->range($myrange) as $r): ?>
      <a<?= $pagination->page() === $r ? ' aria-current="page"' : '' ?> href="<?= $pagination->pageURL($r) ?>">
        <?= $r ?>
      </a>
    <?php endforeach ?>

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

  </nav>

</main>

<?php snippet('footer') ?>

Although the Range is set to 5, only four Range fields are displayed on the “/notes” and “/notes/page;2” pages. Only when at least the third page ("/notes/page;3") is called, the range links of five pages are displayed.


Since this did not occur under Kirby 2.x, I searched for the error by comparing the two codes of Kirby 2.x and Kirby 3.x.

Look at the code

            $end   += abs($start);

at
https://github.com/getkirby/kirby/blob/master/src/Toolkit/Pagination.php#L357

I think, it should look like

            $end   += abs($start)+1;

Please correct Kirby at Github.

Hint:
As experts have seen at “;” in the paths, I use a Windows webserver. But this has no effect on the error.

May I ask that someone from the Kirby team (@bastianallgeier, @texnixe, …) checks this bug report and, if I’m right, creates a corresponding issue on github.
The bug fix is already included in my bug report.

It’s a nasty bug. Thanks!

@anon77445132 It looks like a bug. Can you create an issue on GitHub please?

1 Like

It’s a bug, yes, but I don’t think the proposed solution works for even ranges?

1 Like

Unfortunately I can’t do that, because I don’t have (and don’t want) an account there.

As I have written, my code is like the code of Kirby 2.x.

And the default range is 5 and this shows the error.

Nop, i’ll create for you :wink:

1 Like
1 Like

Thank you very much for your and @pixelijn work on my issue!

@pixelijn and @byybora:

After some tests, I suggest to change the code of

to

    public function range(int $range = 5): array
    {
        $page  = $this->page();
        $pages = $this->pages();
        $start = 1;
        $end   = $pages;

        if ($pages <= $range) {
            return range($start, $end);
        }

        $start = $page - (int)floor($range/2);
        $end   = $page + (int)floor($range/2);

        if ($start <= 0) {
            $end   += abs($start) + ($range % 2 !== 0);
            $start  = 1;
        } elseif ($end > $pages) {
            $start -= $end - $pages - ($range % 2 === 0);
            $end    = $pages;
        } else {
            $start += ($range % 2 === 0);
        }

        return range($start, $end);
    }

I’m sure this will solve this problem completely, no matter if the range is even or odd.

@bastianallgeier:

Sorry, your patch https://github.com/getkirby/kirby/commit/351e2390800ccc534a0cca5cd59142a20408b2ae does not solve this problem.

Please e.g. look at


You may want to change your code to something like:

    public function range(int $range = 5): array
    {
        $page  = $this->page();
        $pages = $this->pages();
        $start = 1;
        $end   = $pages;

        if ($pages <= $range) {
            return range($start, $end);
        }

        $middle = (int)floor($range/2);
        $start  = $page - $middle + ($range % 2 === 0);
        $end    = $start + $range - 1;

        if ($start <= 0) {
            $end   = $range;
            $start = 1;
        }

        if ($end > $pages) {
            $start = $pages - $range + 1;
            $end   = $pages;
        }

        return range($start, $end);
    }

[Updated:]
I have changed ($range % 2 == 0) to ($range % 2 === 0) in my code of this reply
[/Updated]

Who would have thought that a simple piece of code to generate such a range would be so complicated. Your code doesn’t work either for other range setups in our unit tests. I will check again.

1 Like

I’m sorry, your code was actually right. I made a mistake in my test setup :see_no_evil: All tests pass now and I created tests for your cases above as well. Do you have a chance to test the latest version on the develop branch?

1 Like

The new code from the develop branch runs very well without any error. :white_check_mark:

Thank you very much for your work on this and on Kirby. :smiley: