Extending video.php snippet to dynamically serve all videos in a folder

Hi,
following Bastian’s tutorial to embed html5 videos on a kirby page, I was able to further extend it to my own needs:
I figured out a way (not sure if the smartest) to dynamically replace the video filename (e.g video.mp4 within the $videos = array) to the video files’ names present in that specific folder.

<?php $slideshow_videos = $page->videos(); ?>

<!-- get all videos' filename? -->
<?php foreach($slideshow_videos as $filename_video): ?>
  
<?php
  $video_name = $filename_video->name();

  // fetch all video formats we need    
  $videos = array(
    $page->videos()->find($video_name . '.mp4'),
    $page->videos()->find($video_name . '.webm'),
    $page->videos()->find($video_name . '.ogg'),
  );
 
  snippet('video', array(
    'videos' => $videos,
    'thumb'  => $page->images()->find('video.jpg')
  ));
?>

<?php endforeach ?>

The video.php snippet that Bastian shared has also a foreach loop, so at the moment I get, when adding only 2 videos in 3 formats, all 6 videos, instead of 2.

<?php
// stop without videos
if(empty($videos)) return;
// set some defaults
if(!isset($width))    $width    = 400;
if(!isset($height))   $height   = 300;
if(!isset($preload))  $preload  = true;
if(!isset($controls)) $controls = true;
// build the html tags for the video element
$preload  = ($preload)  ? ' preload="preload"'   : '';
$controls = ($controls) ? ' controls="controls"' : '';
?>

<video width="<?php echo $width ?>" height="<?php echo $height ?>"<?php echo $preload . $controls ?>>
  <?php foreach($videos as $video): ?>
  <source src="<?php echo $video->url() ?>" type="<?php echo $video->mime() ?>" />
  <?php endforeach ?>
  <?php if(isset($thumb)): ?>
  <img src="<?php echo $thumb->url() ?>" alt="<?php echo $thumb->title() ?>" />
  <?php endif ?>
</video>

How can I either avoid or merge the double foreach loop?

1 Like

[For anybody’s future reference]

So, since the duplication problem is due to the

<?php foreach($slideshow_videos as $filename_video):
  $video_name = $filename_video->name();
  (...)

wrapping the $videos = array function, I thought that I need to filter the foreach loop to take only one value per video, meaning picking only one filename amongst the three filename with different file extension that there are in the folder.

For this, I tried to use pluck. Together with str::split() it now works!

Updated function:

<?php 
$slideshow_video = $page->videos()->pluck('name', ',', true);
foreach(str::split($slideshow_video) as $filename_video):

// fetch all video formats we need    
$videos = array(
  $page->videos()->find($filename_video . '.mp4'),
  $page->videos()->find($filename_video . '.webm'),
  $page->videos()->find($filename_video . '.ogg'),
);

snippet('video', array(
  'videos' => $videos,
  'thumb'  => $page->images()->find($filename_video . '.jpg')
));

endforeach 
?>
3 Likes