How can I create a collection of all images&videos from all of my blocks?

I would like to display all images and videos from all of my blocks at once.

I think I first have to create a collection which pulls all images and videos from every block. Then I can render every item in a foreach loop.

But how do I create such a collection?
What do I have to add to the following?

<?php 
   $allImagesAndVideos = $page->slider()->toBlocks();
?>
<?php foreach ($allImagesAndVideos as $item): ?>
// image / video
<?php endforeach ?>

My blocks contain images and videos:
(sliderblock.php)

<div class="image-video-box">
    <?php if($leftImage = $block->leftImage()->toFile()): ?>
        <div class="left-element">
            <?php if($leftImage->type() == 'image'): ?>
                <img src="<?= $leftImage->url() ?>">
            <?php endif ?>
            <?php if($leftImage->type() == 'video'): ?>
                <div class="left-video-wrapper">
                    <video playsinline loop autoplay muted>
                        <source src="<?= $leftImage->url() ?>" type="video/mp4">
                    </video>
                </div>
            <?php endif ?>
        </div>
    <?php endif; ?> 
    <?php if($rightImage = $block->rightImage()->toFile()): ?>
        <div class="right-element">
            <?php if($rightImage->type() == 'image'): ?>
                <img src="<?= $rightImage->url() ?>">
            <?php endif ?>
            <?php if($rightImage->type() == 'video'): ?>
                <div class="right-video-wrapper">
                    <video playsinline loop autoplay muted>
                        <source src="<?= $rightImage->url() ?>" type="video/mp4">
                    </video>
                </div>
            <?php endif ?>
        </div>
    <?php endif; ?>
</div>

My block blueprint:
(sliderblock.yml)

name: Slider Block
icon: images
preview: fields
wysiwyg: true
fields:
  leftImage:
    label: Left image / video
    type: files
  rightImage:
    label: Right image / video
    type: files

(I’m using a plugin which enables to upload local videos like images to the block)

Background: I am displaying blocks on the desktop version which can include more than one image. These images are shown side by side. There is always only one Block visible and by click, the next block is shown. But on mobile I want a block to show just one image at a time, but the next image inside the block should be displayed next. So I think the easiest would be to not use blocks on mobile but simply loop through any image/video out of every block and let the user click through them.

Thanks in advance! :slight_smile:

If you can’t just get all images and videos from the page, then you would have to loop through all blocks and each field in each block and convert that to a file object.

foreach ($page->blocks()->toBlocks() as $block) {
  if ($file = $block->leftImage()->toFile()) {
    // do something
  }
  if ($file = $block->rightimage()->toFile()) {
    // do something
  }
}

so basically the same as your code above, only probably with different markup. Wondering if it wouldn’t make more sense to adapt the mobile view via CSS classes.

1 Like