Randomize the hero background

I would like to randomize the hero background taking images from this folder: /assets/img/home/…jpg

I’m trying to use this code: Randomimage.

This is the result:

It doesn’t seem to work, how can I solve it?

Thanks :slight_smile:

That’s old code. But if you change the function like this

function randomimage($dir) {
  $files = dir::read(kirby()->roots()->index() . '/' . $dir);
  return url($dir . '/' . a::first($files));

it will work.

1 Like

Thank you Sonja, it work :wink:

Is possible, also, adding metadata with each random image?

For example the alt and figcaption:

  <img src="<?= randomimage('assets/img/2017'); ?>" alt="<?...?>">

Thanks for the help.

Do you want to get the metadata from the exif data?

No, I just want the possibility to adding (manually) more information about the image.

In this case, for example, the alt and figcaption texts.

I think is something like described here, but not with the panel.


Yes, it is possible, checkout the docs about adding meta data to files: https://getkirby.com/docs/content/media

You can also add a blueprint to control the fields: https://getkirby.com/docs/panel/blueprints/file-settings#file-fields

Yes, I saw it, but I think it’s a little different in this case because the images are taken randomly.

Maybe I’m wrong, can you show me a working example?

As far as I know, you can’t add meta data to files in the assets folder, and can’t define the fields for that in a blueprint. The Panel doesn’t have access to files in the assets folder. But you could add the files to the site folder instead.

Ok, I have added the images in the content folder.

I would pick them randomly and filtered by (banner-). How can I do starting from this code:

   $images = $page->images()->filterBy('filename', '*=', 'banner-');
   foreach($images as $file) {
   $image_url = $file->images()->url();
   $caption = $file->caption();
      echo '<figure>';
      echo '<img src="' . $file->url() . '" alt="' . $caption . '">';
      echo '<figcaption><p>' . $caption . '</p></figcaption>';
      echo '</figure>';

For now I get the list of all images and caption (correctly). I just want one result for each refresh.


   $image = $page->images()->filterBy('filename', '*=', 'banner-')->shuffle()->first();
   $image_url = $image->url();
   $caption = $image->caption();
   <img src="<?= $image_url ?>" alt="<?= $caption ?>">
   <figcaption><p><?= $caption ?></p></figcaption>

On a side note: It’s considered good style not to echo HTML tags… and makes life easier.

1 Like

Thanks Sonja, it work :wink:

I wish do the same thing described here.

The user add a few images from the panel using the visual select plugin Kirby-Selector: https://github.com/storypioneers/kirby-selector

But, I want show just one image from the selected and random, is possible?

For example:

$hero = $page->hero()->split();
foreach($hero as $heroImage) : ?>
<div class="hero" style="background-image: url(<?php echo $page->images()->find($heroImage)->url() ?>);">
<?php endforeach ?>

Thanks :slight_smile:

You can use array_rand to get an arbitrary element of the array:

$hero = array_rand($page->hero()->split(), 1);
<div class="hero" style="background-image: url(<?php echo $image = $page->image($hero)? $image->url(): '' ?>);">

Thanks Sonja, but I get an error with the Kirby CMS Debugger:

syntax error, unexpected ‘)’

Is correct the code?

Certainly not correct, if it throws an error :wink:

Corrected now.

Yes, the echo :wink:

But, I get no url() now:

I have already selected the images:

And, this is the blueprints:

    label: Cabeçalho
    type: selector
    mode: multiple
    filter: hero
        - image


Sorry, I made a mistake. array_rand()only returns the key. This should work now, please note that I added parenthesis around the ternary expression as well.

    $imagelist = $page->hero()->split();
    $key = array_rand($imagelist);
    $hero = $imagelist[$key];
<div class="hero" style="background-image: url(<?php echo ($image = $page->image($hero))? $image->url(): '' ?>);">
1 Like

Another great help, thank you Sonja.

Everything works perfectly :sunglasses:

1 Like

From this code if the user don’t select any image (for mistake) show an error.

Is possible do an if-else statements to show at least one image?

Maybe an image from the /assets/ folder, for example.