Hi,
I’m following Kirby’s random content guide to fetch an array of 3 random images from random pages, however I’d like for the images to be from a specific file selector field instead of all images on that page.
<?php
$references = page('exhibitions')
->children()
->references()
->shuffle()
->limit(3)
->toFiles();
foreach($references as $reference): ?>
<li>
<img src="<?= $reference->url() ?>">
</li>
<?php endforeach ?>
In my code “references()” is the image selector field, which I’m using in place of all “images()”. For some reason this gives me an error, though when I use “images()” without the toFiles() method it works fine. I have images uploaded to the specified image selector field too, so that shouldn’t be an issue.
Any help would be enormously appreciated!
Update: Is the problem actually with trying to fetch images from a files field on multiple pages?
I tried the following and it worked:
<?php
$references = page('exhibitions')
->children()
->shuffle()
->first()
->references()->toFiles()
->shuffle()
->limit(3);
foreach($references as $reference): ?>
<li>
<?= $reference->url() ?>
</li>
<?php endforeach ?>
But ideally I could get random images from the “references” field on all children pages of “exhibitions”…
You cannot call a field on a collection of pages.
There are different ways to achieve this, either looping through the pages or filtering the files. Maybe the last example is the best.
<?php
$files = new Files();
$exhibitions = page('exhibitions')->children();
foreach ($exhibitions as $exhibition) {
$files->add( $exhibition->references()->toFiles());
}
$files = $files->shuffle()->limit(3);
foreach($files as $reference): ?>
<li>
<img src="<?= $reference->url() ?>">
</li>
<?php endforeach ?>
Alternatively:
$files = new Files();
$fields = page('exhibitions')->children()->pluck('references');
foreach ($fields as $field) {
$files->add($field->toFiles());
}
dump($files);
// then as above
Or (same as first example, only using map()
instead of the foreach
loop):
$files = new Files();
page('exhibitions')->children()->map(fn ($child) => $files->add($child->references()->toFiles()));
$files = $files->shuffle()->limit(3);
In all three examples, we instantiate a new Files object and then loop through the pages/fields to add the files from the references
field to this object.
Or filtering the files by whether or not they are contained in the field:
$files = page('exhibitions')->children()->files()->filter(fn ($file) => $file->parent()->references()->toFiles()->has($file))->shuffle()->limit(3);
If the files in your references field have a template assigned, you could first filter by that template:
$files = page('exhibitions')->children()->files()->template('yourTemplateName')->filter(fn ($file) => $file->parent()->references()->toFiles()->has($file))->shuffle()->limit(3);
Thanks @texnixe ! I had a feeling I didn’t quite understand fetching content from page collections yet; your thorough explanation with various approaches was really helpful. I ended up using the third example and it worked beautifully