Absolute path, not URL, to random image …


Dear community,

I found a lot partial solutions, but I think most of them looks very complex. I’m looking for a way to load a random image from /assets/gif/

Is there some nifty one-liner like (pseudo-code) <?php echo $roots->assets() . 'gif/' . images()->shuffle()->first(); ?>? But I’d please like to have a path starting with /assets/, not a full external URL to my domain + path …

Thank you in advance. : )


I’m not sure if I understood you correctly but you may be looking for kirby()->roots()->assets(). That’s the absolute path to the assets folder


Dear @pedroborges, you did … I thought $roots would be short for kirby()->root()

Though, I’m not sure on how to pass my directory, gif/, there and how to then get random images. Would be great if it would be possible as easy as ->images()->shuffle()->first() … but I’m not sure if that then gives the filename of the image, probably not heh.


No, you can’t any of the page or collection methods here, because you are dealing with a folder outside of content.

$files = glob(kirby()->roots()->assets() . '/images/*.*');
$random = array_rand($files);
$file = $files[$random];


Thank you, @texnixe.

Unfortunately, dump() seems to wrap it’s content in <pre></pre> tags … besides, this way I get a absolute file-system path like /Users/user/Sites/kirby-site-one/assets/images/image-name.gif

I wonder if there’s no file-system-independent way of accessing just kirby’s root.

Another option would be to use javascipt for this. I’ll think about that option for some moments … but PHP would be noscript compatible.


What do you want to do with the file, of course you don’t have to dump it, it was just intended to check if you get a result.


I want to set a random background-image …

<div id="bg" style="background-image:url(/assets/gif/<?php echo $file ?>);"></div>

$files = array();
// http://php.net/manual/de/class.directoryiterator.php
$iterator = new \DirectoryIterator(kirby()->roots()->assets() . '/gif');
foreach ($iterator as $file) {
    if($file->isFile() && $file->getExtension() == 'gif') {
        $files[] = $file->getFilename();
if(count($files)) {
  $random = array_rand($files);
  $file = $files[$random];
<div id="bg" style="background-image:url(/assets/gif/<?php echo $file ?>);"></div>

Alternative: How about putting the files into the content folder as site images?

$file = $site->images()->shuffle()->first()->filename();

Lot less code…


Thank you very much for this beautiful solution. Learned a lot! : )

Unfortunately I’m doing very hard with PHP, heh.


<?php $file = $site->images()->shuffle()->first()->filename();

Are you sure that can work?

It appears you’re treating the return value of shuffle() as an array, but i’ve read it’s not an array-- it’s a boolean:

shuffle returns a boolean indicating success or failure. Your result will be in the passed variable, not in the function return value.

Maybe you can nest these functions instead of chaining them?


Shuffle is not shuffle. Here we are dealing with a collection method from the collection class, so the return value from $site->images()->shuffle() is again a collection (files object in this. case) not a boolean. See the documentation.

However, you shouldn’t use. the code as above, but make sure you have a file object before you call the filename()method:

if($file = $site->images()->shuffle()->first()) {
  echo $file->filename();