Dynamic sorting for prev/next navigation

I have a prev/next snippet that I want to use for various filter queries. The code is quite extensive and only a small area changes at a time:

->sortBy('date', 'desc')
->sortBy('num', 'asc')
->sortBy('title', 'asc') 
…

I’m missing logic on how to make this area dynamic, so as not to duplicate the snippet x times. That would be unnecessarily complex.

The parent page is an overview page with all children.
The snippet is always used on the parent page and applies to the template of the children pages. <?php snippet('prevnextdate') ?>

site/snippets/prevnextdate.php
<?php if ($page->prevnext()->toBool() === true): ?>
<section class="bg-black p-0">
<div class="container">
<div class="row row-cols-1 row-cols-lg-2 g-1 d-flex justify-content-center">

<?php $collection = $page->siblings()->listed()->sortBy('date', 'desc');
if ($prev = $page->prevListed($collection)): $prevCover = $prev->cover()->toFile(); ?>
<div class="col">
<a href="<?= $prev->url() ?>" class="text-white bg-extra-dark-gray bg-red-hover d-flex justify-content-between align-items-center h-100 pe-4 wow animate__fadeIn">
<?php if ($prevCover): ?>
<img src="<?= $prevCover->crop(100, 100, 'center')->url() ?>" alt="<?= $prevCover->alt()->esc() ?>">
<?php endif ?>
<i class="fa-sharp fa-regular fa-angle-left fa-xl mx-4"></i>
<span class="flex-fill lh-1 text-truncate text-start py-3">
<span class="text-extra-large d-block"><?= $site->labelPrevProject()->html() ?>:</span>
<span class="alt-font text-25"><?= $prev->title()->html()->excerpt(80) ?></span>
</span>
</a>
</div>
<?php endif ?>

<?php if ($next = $page->nextListed($collection)): $nextCover = $next->cover()->toFile(); ?>
<div class="col">
<a href="<?= $next->url() ?>" class="text-white bg-extra-dark-gray bg-red-hover d-flex justify-content-between align-items-center h-100 ps-4 wow animate__fadeIn">
<span class="flex-fill lh-1 text-truncate text-end py-3">
<span class="text-extra-large d-block"><?= $site->labelNextProject()->html() ?>:</span>
<span class="alt-font text-25"><?= $next->title()->html()->excerpt(80) ?></span>
</span>
<i class="fa-sharp fa-regular fa-angle-right fa-xl mx-4"></i>
<?php if ($nextCover): ?>
<img src="<?= $nextCover->crop(100, 100, 'center')->url() ?>" alt="<?= $nextCover->alt()->esc() ?>">
<?php endif ?>
</a>
</div>
<?php endif ?>

</div>
</div>
</section>
<?php endif ?>

Result:

This should then be defined outsite of the snippet, and the relevant collection passed to the snippet function as argument, see snippet documentation how to do that.

Do you mean this section?

Or would I need to create a “snippet-within-a-snippet” in my case?

No, you don’t need a snippet in a snippet, you pass the collection you define in the template or controller as argument to the snippet

// template where you call snippet
$collection = $page->siblings()->listed()->sortBy('date', 'desc'); // remove this part from the snippet

snippet('prevnextdate', ['collection' => $collection]);
1 Like

This worked right away and makes it so easy.
So far I’ve only used snippets in the base function.
Passing variables to a snippet is something I used for the first time today.
Thanks a lot for your great support :clap:

This is what my pimped code looks like now:

<?php 
$collection = $page->siblings()->listed()->sortBy('title', 'asc');
snippet('prevnext', compact('collection'));
snippet('footer'); 
?>