Page Media as Slideshow

Is there a way I could get slideshow from page media images if more than 1 image is added?

My template uses single page media image as a header background, so I was wondering if I could get multiple images to be slideshow, any image inserted in Page Media.


Yeah for sure, I have something very similar on a grav site:

I personally use siema.js - a super small slider library and add some styles over it. I personally have it as a full screen background.

In my twig file I have:

<div class="slider">
{% for slide_images in page.header.imageslider %}
{% set imgHeight =[].height %}
<div class="slider-slide"
		background-image: url('{{[].quality( 80 ).url }}');
		width: 100%;
		height: 100vh;
		max-height: 100vh;
		background-size: cover;
		background-position: center center;
		background-repeat: no-repeat;">
{% endfor %}

You can obviously put all those styles into a scss file and I have it as a background-image in the inline style only due to it being easier to have a nice fullscreen image. You can use '{{[].quality( 80 ).url }}' with derivatives and src-set and have them lazyload as well.

In this case I have a custom page blueprint for my homepage, it looks like this:

extends@: default

              unset@: true

              type: file
              label: Image Slider Content
              destination: '@self'
              style: vertical
              multiple: true
              preview_images: true
              limit: 10
                - image/*

Now when I select a page type of home in admin, I will see an media upload field. I can add images in there and they will display on the homepage.

Now for a little bit of js stuff:

Like I mentioned earlier I use (more docs: for the slider. It is super lightweight and barebones.

In my home.html.twig file I have this snippet to initiate the slider:

{% block javascripts %}
{{ parent() }}
{% do assets.addJs( 'theme://dist/scripts/siema.min.js', {'priority':95, group:'bottom', loading:'async'} ) %}
{{ assets.js('bottom') }}
{% endblock %}

{% block bottom %}
	{{ parent() }}
		const bgSlider = new Siema({
			selector: '.slider',
			duration: 150,
			easing: 'linear',
			loop: true,
			draggable: false,
			multipleDrag: false
		setInterval(() =>, 10000);
{% endblock %}

You can also grab the image height and width if you would like, in case you need a specific dimension for maybe a lazyload container that is the same size as the image that will load in.

I do something like this:

const containerHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
const containerWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
document.getElementsByClassName('slider')[0].style['height'] = containerHeight + 'px'
document.getElementsByClassName('slider')[0].style['width'] = containerWidth + 'px'

I also add a little bit of css to the slider class outside of the twig file, adding below in case it will help out.

.slider {
	width: 100%;
	max-width: 100vw;
	max-height: 100vh;
	overflow: hidden;
	-webkit-overflow-scrolling: touch;
	position: fixed;
	top: 0;
	bottom: 0;
	right: 0;
	left: 0;

	&:after {
		content: "";
		background-color: rgba( palette( black ), 0.6 );
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		position: absolute;

I needed an idiot-proof way for my client to upload any image that is of a min-width (for larger screens) and it looks nice as a giant background slider. Your needs may be a bit different so this can for sure be simplified a bunch :slight_smile: