Converting a WordPress gallery into a responsive slideshow without a plugin (PHP code included)
A client needed a slideshow in their post content. I tried a number of slideshow plugins, but all required you create the slideshow before creating the post, and most had more features than I needed. So I wrote a function to convert standard WordPress galleries to slideshows.
From your post edit screen, select “add media”
Select “create gallery” and choose the images you want to include:
The images will appear as a gallery in the edit screen:
But when rendered in your post, they’ll show up as a slideshow:
Add the PHP code below to your functions.php
file to convert WordPress galleries to slideshows.
Here’s the code:
function gallery_to_slideshow( $output, $attr, $instance ) {
$args = array(
'post__in' => explode( ',', $attr['ids'] ),
'post_type' => 'attachment',
'post_mime_type' => 'image',
'no_found_rows' => true,
'posts_per_page' => - 1,
'post_status' => 'any'
);
$query = new \WP_Query( $args );
$slide_count = count( $query->posts );
if (0 === $slide_count) {
return '';
}
ob_start();
?>
<div
class="sem-gallery"
id="gallery-<?php echo $instance ?>"
data-current="0"
data-count="<?php echo $slide_count ?>"
>
<div style="
position: relative;
width: 100%;
aspect-ratio: 16/9;
overflow: hidden;
">
<div class="sem-gallery-slides"
style="
top: 0;
bottom: 0;
left: 0;
position: absolute;
display: flex;
width: <?php echo $slide_count * 100 ?>%;
">
<?php foreach ( $query->posts as $i => $post ) : ?>
<div style="
width: <?php echo 100 / $slide_count ?>%;
background-color: #eee;
background-image: url(<?php echo wp_get_attachment_url($post->ID) ?>);
background-size: contain;
background-position: center;
background-repeat: no-repeat;
"
></div>
<?php endforeach; ?>
</div>
</div>
<div style="
display: flex;
margin-top: 1rem;
gap: 1rem;
justify-content: center;
">
<button type="button"
data-action="prev"
class="button">Previous
</button>
<button type="button"
data-action="next"
class="button">Next
</button>
</div>
</div>
<script>
jQuery(function ($) {
$('#gallery-<?php echo $instance ?> button[data-action]').click(function () {
const $this = $(this);
const $wrapper = $this.closest('.sem-gallery');
const current = parseInt($wrapper.data('current'));
const count = parseInt($wrapper.data('count'));
const currentNew = 'next' === $this.data('action')
? current + 1 < 0 || current + 1 + 1 > count ? 0 : current + 1
: current - 1 < 0 ? count - 1 : current - 1;
const $slides = $('.sem-gallery-slides', $wrapper);
$slides.animate({ left: `-${currentNew * 100}%` });
$wrapper.data('current', currentNew);
});
p;
});
</script>
<?php
$to_return = ob_get_contents();
ob_end_clean();
return $to_return;
}
add_filter( 'post_gallery', 'gallery_to_slideshow', 99, 3 );