Turn Shortcode Gallery into Carousel in WordPress 4.4

I searched for existing plugins that could do carousels in wordpress posts but they turned out to not display correctly in WordPress 4.4 which released recently.

Carousel Ultimate

Agnosia Bootstrap Carousel by AuSoft

Is there a carousel option available that makes it easy to add captions/images/links and the number of columns for WordPress posts compatible with the latest release?

Or is it possible to add a custom script to extend the existing gallery shortcode?

1 Answer
1

You can piggyback off of the WP Gallery shortcode to render your slider. This example is adapted from the Owl Carousel Demo / Docs.

To use it, create a WP Gallery and add the attribute owl="true". Obviously there are better ways to enqueue scripts but this can guide you on gallery modifications.


 

NOTE: It’s best to put this shortcode in a plugin but it’s possible to add to your functions.php — at that point it will be theme specific. If you apply to a default theme and update then these changes will be overwritten. You have been warned.

For an easy location put it into wp-content/mu-plugins/gallery-owl-shortcode.php. It will always load and you don’t need to make a full plugin.


UPDATE:

I realized this code could repeat a lot of JS and CSS on a blog page if every post had gallery so I added a check to see if that portion has already been included. The downside is that all galleries have the same settings.


<?php

add_shortcode( 'gallery', 'modified_gallery_shortcode' );

function modified_gallery_shortcode($attr)
{
    // Replace WP gallery with OWL Carousel using gallery shortcode -- just add `owl=true`
    //
    // 

    if( isset($attr['owl']))
    {
        $attr['itemtag']="span";

        $output = gallery_shortcode($attr);

        $output = strip_tags($output,'<a><img><span><figcaption>'); // remove extra tags, but keep these
        $output = str_replace("span", "div", $output); // replace span for div -- removes gallery wrap
        $output = str_replace('gallery-item', "item", $output); // remove class attribute

        $output = "<div class=\"owl-demo\" >$output</div>"; // wrap in div

        // begin styles and js

        static $js_loaded; // only create once
        if( empty ( $js_loaded )) {

        ob_start();
        ?> 
        <style>
            .owl-demo .item{
                margin: 3px;
            }
            .owl-demo .item img{
                display: block;
                width: 100%;
                height: auto;
            }
        </style>
        <script defer src="https://owlgraphic.com/owlcarousel/owl-carousel/owl.carousel.js"></script>
        <script>
            jQuery('head').append('<link defer id="owl-carousel-css" rel="stylesheet" href="http://owlgraphic.com/owlcarousel/owl-carousel/owl.carousel.css" type="text/css" />');
            jQuery('head').append('<link defer id="owl-theme-css" rel="stylesheet" href="http://owlgraphic.com/owlcarousel/owl-carousel/owl.theme.css" type="text/css" />');

            jQuery(document).ready(function () {

                // pulling example from -- including CSS
                // http://owlgraphic.com/owlcarousel/demos/images.html

                // notice I replaced #id with .class for when you want to have more than one on a page
                jQuery(".owl-demo").owlCarousel({

                    autoPlay: 3000, //Set AutoPlay to 3 seconds

                    items: 1,
                    itemsDesktop: [1199, 1],
                    itemsDesktopSmall: [979, 1] // adaptive image count
                });
            });
        </script>
        <?php
        $js_loaded = ob_get_clean(); // store in static var

        // add the HTML output
        $output .= $js_loaded;
        }
    }
    else
    {
        // default gallery
        $output = gallery_shortcode($attr);
    }

    return $output; // final html

ALTERNATE

So the above code works but it might be nice to create a completely new interface rather than hacking at the gallery that WP provides. Since the IDs are passed in the attributes you can build your own solution from scratch — including a custom link — just make sure to register the link field.

if( isset($attr['owl']))
{
    $image_ids = explode(',', $attr['ids']);

    $output="";
    $size = isset($attr['size']) ? $attr['size'] : 'medium';

    foreach($image_ids as $attachment_id) {

        // http://wordpress.stackexchange.com/questions/1051/how-to-retrieve-an-image-attachments-alt-text

        $img_src="";//esc_url(  wp_get_attachment_image_url( $attachment_id, $size ) );
        $img_srcset = esc_attr( wp_get_attachment_image_srcset( $attachment_id, $size ) );

        $alt = esc_attr ( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) );
        $link = esc_attr ( get_post_meta($attachment_id, '_gallery_link_url', true) );
        $the_attachment = get_post($attachment_id); // post
        $caption = esc_attr ( $the_attachment->post_excerpt );

        $img = "<img src=\"{$img_src}\" srcset=\"{$img_srcset}\"
             sizes=\"auto\" alt=\"{$alt}\">";
        $link = empty($link) ? $img : "<a href=\"{$link}\" >{$img}</a>";
        $caption = "<figcaption>{$caption}</figcaption>";
        $item = "<div class=\"item\">{$link}{$caption}</div>";

        $output .= $item;
    }

    $output = "<div class=\"owl-demo\" >$output</div>"; // wrap in div

    //... include JS & CSS stuff
}

Register Custom Link field on gallery attachment

add_filter( 'attachment_fields_to_edit', 'apply_filter_attachment_fields_to_edit', null, 2 );
add_filter( 'attachment_fields_to_save', 'apply_filter_attachment_fields_to_save', null , 2 );
function apply_filter_attachment_fields_to_edit( $form_fields, $post )
{
    // Gallery Link URL field
    $form_fields['gallery_link_url'] = array(
        'label' => 'Gallery Link URL',
        'input' => 'text',
        'value' => get_post_meta( $post->ID, '_gallery_link_url', true ),
    );
    return $form_fields;
}

function apply_filter_attachment_fields_to_save( $post, $attachment ) {
    // Save our custom meta fields
    if( isset( $attachment['gallery_link_url'] ) ) {
        update_post_meta( $post['ID'], '_gallery_link_url', $attachment['gallery_link_url'] );
    }
    return $post;
} // End function apply_filter_attachment_fields_to_save()

Leave a Comment