Absolute path, not URL, to random image …


#1

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. : )


#2

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


#3

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.


#4

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];
dump($file);

#5

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.


#6

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.


#7

I want to set a random background-image …

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


#8
<?php
$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?

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

Lot less code…


#9

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

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


#10

<?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.
https://stackoverflow.com/questions/5841834/shuffle-order-of-images-in-php/5841866#comment49270897_5841883

Maybe you can nest these functions instead of chaining them?


#11

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();
}