I followed the guide “virtual pages from image gallery” (Virtual pages from image gallery | Kirby CMS) to create an image gallery with virtual pages. Everything works as expected, but now I want to add videos to the gallery, too, with the same behaviour (virtual page for each video). The videos will be files hosted on the server.
Has anybody done this yet? I could not find anything via the search, but thought I’d ask here before attempting this myself. Pointers in the right direction are much appreciated!
The procedure would basically be the same, you just need to adapt the relevant steps. It depends a bit on whether you want to mix images and videos, or just use videos.
I’d like to mix them, so that the gallery shows images and videos.
Ok, in that case, you need to replace those instances where the code filters by images (the models), with a filter by images and videos, and in the template also make sure to differentiate by file type to use the image/picture tag for images, and the video tag for videos.
Can’t go through the complete recipe in detail now
I do exactly this in my Hepburn theme. Hepburn 4 Theme for Kirby 4 - Hash&Salt
the basics are i have a file hook that sets the template for video and images basid on file type like like below. The reason for this is because on a files feild you can only set one blue print for the files and you need different feilds for videos such as a poster image. The hook in the confg file
'file.create:after' => function ($file) {
if ($file->parent()->template() == 'album') {
if ($file->type() == 'video') {
$file->update([
'template' => 'video'
]);
} elseif ($file->type() == 'image') {
if (!$file->template() == 'poster') {
$file->update([
'template' => 'shot'
]);
}
}
}
}
From there i have a page model for the list of images and videos
<?php
class AlbumPage extends Page
{
// Use images as pages
public function children(): Pages
{
$mediapages = [];
foreach ($this->files()->filterBy('template', 'in', ['shot', 'video']) as $media) {
if($media->type() == "image") {
$mediapages[] = [
'slug' => $media->name(),
'num' => $media->sort()->isNotEmpty() ? $media->sort()->value() : null,
'template' => 'image',
'model' => 'image',
];
} elseif ($media->type() == "video") {
$mediapages[] = [
'slug' => $media->name(),
'num' => $media->sort()->isNotEmpty() ? $media->sort()->value() : null,
'template' => 'video',
'model' => 'video',
];
}
}
return Pages::factory($mediapages, $this);
}
}
The reson for the not in there (!) is because you dont want the poster image for the video showing up as part of the gallery images.
And then seperate models for images and videos
```php
<?php
class ImagePage extends Page
{
// Find the shot image in the set
public function shot()
{
$shot = $this->parent()->images()->findBy('name', $this->slug());
return $shot;
}
}
and
<?php
class VideoPage extends Page
{
// Find the shot image in the set
public function shot()
{
$shot = $this->parent()->videos()->findBy('name', $this->slug());
return $shot;
}
}
<?php
class ImagePage extends Page
{
// Find the shot image in the set
public function shot()
{
$shot = $this->parent()->images()->findBy('name', $this->slug());
return $shot;
}
}
From there you can setup controllers to match the image and video pages as you see fit.
I hope that helps.
Thanks for the fast and helpful responses! I will look into it and see how it goes. I am a designer, not a developer (that’s why I used the guide for the virtual images, it was easy enough for me to understand and follow along). I will let you know how it ends up.
Short update: I tried to modify the image gallery with virtual pages, but could not get it to work using video files AND images. But in the process, I realised I do not need the virtual pages for now, so I settled with a gallery page that shows images and videos in one gallery, just without the virtual pages.