Pagination with 0 element

Hello!

I had a pagination that worked, but now, I wanted to add filters, the filters work, but when I have 0 elements after filtering (which can appen when no element match filters), I get a weird situation.

I have a snippet to generate the navigation between page of this pagination :

<nav class="text-gray-800 text-2xl">
	<ul class="space-x-2 flex justify-center items-center">
		<li>
			<a class="flex px-1 py-2" <?php e($hasPrev, 'href='.$pagination->firstPageUrl().'#_') ?>>
				<svg class="inline w-4 h-4 <?= $hasPrev ? 'fill-gray-800' : 'fill-gray-200' ?>">
					<use xlink:href="<?= url('assets/icones/sprite.svg') ?>#first"/>
				</svg>
			</a>
		</li>
		<li>
			<a class="flex px-1 py-2" <?php e($hasPrev, 'href='.$pagination->prevPageUrl().'#_') ?>>
				<svg class="inline w-4 h-4  <?= $hasPrev ? 'fill-gray-800' : 'fill-gray-200' ?>">
					<use xlink:href="<?= url('assets/icones/sprite.svg') ?>#prev"/>
				</svg>
			</a>
		</li>

		<?php foreach ($pagination->range($range) as $n): ?>
			<li class="<?php e($n == $pagination->page(), 'text-white bg-gray-800') ?>">
				<a class="px-2 py-1" href="<?= $pagination->pageUrl($n).'#_' ?>"><?= $n ?></a>
			</li>
		<?php endforeach; ?>

		<li>
			<a class="flex px-1 py-2" <?php e($hasNext, 'href='.$pagination->nextPageUrl().'#_') ?>>
				<svg class="inline w-4 h-4 <?= $hasNext ? 'fill-gray-800' : 'fill-gray-200' ?>">
					<use xlink:href="<?= url('assets/icones/sprite.svg') ?>#next"/>
				</svg>
			</a>
		</li>
		<li>
			<a class="flex px-1 py-2" <?php e($hasNext, 'href='.$pagination->lastPageUrl().'#_') ?>>
				<svg class="inline w-4 h-4 <?= $hasNext ? 'fill-gray-800' : 'fill-gray-200' ?>">
					<use xlink:href="<?= url('assets/icones/sprite.svg') ?>#last"/>
				</svg>
			</a>
		</li>
	</ul>
</nav>

But i get the following error :

Return value of Kirby\Cms\Pagination::firstPageUrl() must be of the type string, null returned

First I don’t understand why $pagination->firstPageUrl() is executed since it is in a conditionnal echo (I tested the value of $hasPrev and it’s effectively false, but beyond that why is null returned and not 1.

Ty by advance :grinning:.

The e function from the Kirby toolkit is just a function. It doesn’t have the “power” to short-circuit its parameter evaluation. This means that before even calling e(), all its arguments are evaluated.

Imho the Pagination::firstPageUrl shouldn’t however throw an error for empty sets. I’d consider that a bug; if the function can return null, the return type should be declared as ?string and not string. You could open an issue on github for that.

In the meantime you could work around the issue with code like this:

<?= $hasPrev ? 'href=' . $pagination->firstPageUrl() . '#_' : '' ?>

The PHP ternary operator does short-circuit the evaluation

Oh didn’t think to it for the e(), but seems logic after you said it :sweat_smile:

And for the work around, I just try it but the result with my pagination navbar is pretty weird.

Ty a lot for your help :smiley:

Is there are reason why you check for $hasPrev for both the firstPageUrl and prevPageUrl, and for and $hasNext for lastPageUrl() and nextPageUrl()? To me, that somehow doesn’t make sense.

In any case, I’d show the pagination only when there are items:

<?php if ($pagination->hasPages()): ?>
  <!-- Rest of code -->
<?php endif ?>

Yep you’re right, could do with one if, here it’s just for code readability / “compactness”.

And yes, then I will show the navbar only if pagination has pages.

Ty a lot :smiley: for help.

Will be fixed in 3.7