Hi, this is my first post here so please bear with me.
I am trying to use Kirby’s $file->prev()
function (see here ) to access the previous image in a foreach loop. The problem is that the function seems to ignore the manual sorting parameter and instead sorts by filename. Any idea what I could be missing/doing wrong?
Thanks!
<?php foreach($page->images()->sortBy('sort', 'asc')->offset(1) as $image): ?>
<p>
Previous image: <?= $image->prev()->filename(); ?><br>
This image: <?= $image->filename() ?>
</p>
<?php endforeach ?>
You need a custom method to achieve that, one that accepts a parameter, it’s the same problem for pages, have a look here: https://github.com/texnixe/kirby-custom-methods/blob/master/page-methods/get-next.php
Thank you. I’ll take a look and report back when I get this working (seems a bit daunting at the moment)…
These should work, if the last index is reached, it starts from the beginning and vice versa; if you don’t want this behaviour, you can change it, so that the functions don’t return anything once they have reached the beginning/end.
file::$methods['getNext'] = function($file, $sort='sort', $direction='asc') {
$siblings = $file->files()->sortBy($sort, $direction );
$index = $siblings->indexOf($file);
$maxIndex = $siblings->indexOf($siblings->last());
if($index === false) return false;
if($index === $maxIndex) return $siblings->nth(0);
return $siblings->nth($index+1);
};
file::$methods['getPrev'] = function($file, $sort='sort', $direction='asc') {
$siblings = $file->files()->sortBy($sort, $direction );
$index = $siblings->indexOf($file);
$maxIndex = $siblings->indexOf($siblings->last());
if($index === false) return false;
if($index === 0) return $siblings->nth($maxIndex);
return $siblings->nth($index-1);
};
Usage:
$file = $page->files()->sortBy('sort', 'desc')->first();
$next = $file->getNext('sort', 'desc');
Handed on a silver platter. This works brilliantly, thank you so much!
I’m in the process of upgrading the project I used this on to Kirby 3 and things have stopped working. I know get a Call to a member function files() on string
error triggered by
$file->files()->offset($offset)->sortBy($sort, $direction );
It’s probably trivial but I’m a bit stuck here… Maybe there are new ways to get prev/next files in a sorted collection by now, too?
Still no dice here. As far as I understand I’m passing an image object to the method, not a string:
<?= $page->images()->first()->getNext('sort', 'asc') ?>`
This is the K3 plugin:
Kirby::plugin('foxacid/getNext', [
'fileMethods' => [
'getNext' => function($file, $sort='sort', $direction='asc') {
$siblings = $file->files()->sortBy($sort, $direction);
$index = $siblings->indexOf($file);
$maxIndex = $siblings->indexOf($siblings->last());
if(($index === false) || ($index === $maxIndex)) return false;
return $siblings->nth($index+1);
}
]
]);
foxacid:
on to Kirby 3
You can use prev()
/next()
with the sorted collection as parameter, see the documentation for those methods.
You can use prev()
/next()
with the sorted collection as parameter, see the documentation for those methods.
That will work for the simple example above, but not inside a loop:
<?php
$sortedImages = $page->images()->sortBy('sort', 'asc')->offset(1);
foreach($sortedImages as $image) {
echo $image->next($sortedImages)
}
?>
What is the point of calling next in this loop? and the code works as expected if you look at this code example:
$sortedImages = $site->index()->images()->sortBy('filename', 'asc')->offset(1);
dump($sortedImages);
foreach($sortedImages as $image) {
dump($image->id());
dump($image->next($sortedImages)?->id());
echo '<hr>';
}
Will always output the current image in the loop and the next one.
1 Like
It’s… complicated.
I’m automating page layouts based on image aspect ratios. For this I check the ratios of previous and next siblings and set layout classes accordingly.
Then please explain what doesn’t work in the above code.
Sorry I checked again and it sure does work. I had a typo in the controller. Many thanks for helping out!