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.
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
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);
$start = 1;
}
if ($end > $pages) {
This file has been truncated. show original
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 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.
Thank you very much for your work on this and on Kirby.