"Poster" image for mp4 <video>. My Code works but I have 3 foreach loops!?!?

Hi!

I want to add a poster images to my mp4 videos. Here is my Code:

list_movies:
  label: Movies
  type: structure
  fields:
    my_video:
      label: Movie
      type: files
      query: page.videos
      width: 1/2
    my_poster:
      label: Poster
      type: files
      query: page.images
      width: 1/2
<?php $movies = $page->list_movies()->toStructure(); ?>
    <?php foreach($movies as $movie): ?>
    <div class="container">
        <div class="row">
            <div class="col-8 offset-2">
                            
                <?php $vids = $movie->my_video()->toFiles();
                foreach($vids as $vid): ?>
                
                    <?php $posters = $movie->my_poster()->toFiles();
                    foreach($posters as $poster): ?>
                        <video controls poster="<?= $poster->url() ?>" class="img-fluid mb-5">
                             <source src="<?= $vid->url() ?>" type="<?= $vid->mime() ?>">
                        </video>
                    <?php endforeach ?>
                    
                <?php endforeach ?>	
                
            </div>
        </div>
    </div>
    <?php endforeach ?>

The Code works. But are the 3 “foreach” loops necessary? Can there be problems?
Is there a way to simplify the code?

Thanks for help.

So each of these structure items has multiple videos? That somehow doesn’t really make sense. If you have only one video per item, then you don’t convert to files and you don’t need a loop. for one video/poster per field, also add max: 1.

Yes you are right. It is only one video per item. I set max: 1.

Ok so it’s:

    <?php $movies = $page->list_movies()->toStructure(); ?>
    <?php foreach($movies as $movie): ?>
    <div class="container">
        <div class="row">
            <div class="col-8 offset-2">
                
            <?php $posters = $movie->my_poster()->toFiles();
            foreach($posters as $poster): ?>
                <video controls poster="<?= $poster->url() ?>" class="img-fluid mb-5">
                    <source src="<?= $movie->url() ?>" type="<?= $movie->mime() ?>">
                </video>
            <?php endforeach ?>
            
            </div>
        </div>
    </div>
    <?php endforeach ?>

I am a bit confused. It works. But do I need the second loop for the poster?

No, you don’t, and there is another issue with your code, which should be:

<?php $movies = $page->list_movies()->toStructure(); ?>
<?php foreach($movies as $movie): ?>
    <?php if ($video =  $movie->my_video()->toFile()): ?>
        <div class="container">
            <div class="row">
                <div class="col-8 offset-2">    
                <?php $poster = $movie->my_poster()->toFile(); ?>
                  <video controls poster="<?= $poster ? $poster->url(): '' ?>" class="img-fluid mb-5">
                        <source src="<?= $video->url() ?>" type="<?= $video->mime() ?>">
                    </video>
                </div>
            </div>
        </div>
    <?php endif; ?>
<?php endforeach ?>
1 Like

Sorry for the late reply.
And thank you that’ll get me further.

But I don’t understand this line though

<?= $poster ? $poster->url(): '' ?>

$poster ? = if clause – right?

but: $poster->url(): '' Why the empty quotation marks?

Any idea where I can find help in the Docs?

Thanks for the help – it’s not easy to code as a designer.

Its a terneray statement (part of PHP, nothing to do with Kirby). Basically a shorthand if/else. Before the ? is the condition, then you have what happens if true or false. After the : is the false. Basically, in this context, you get nothing if $poster is false.

Ahhh ok. Thank you.