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.

https://wordpress.org/plugins/carousel/

https://wordpress.org/plugins/agnosia-bootstrap-carousel/

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

7

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.


 [gallery owl="true" link="none" size="medium" ids="378,377,376,375,374,373"]

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`
    //
    // [gallery owl="true" link="none" size="medium" ids="378,377,376,375,374,373"]

    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="http://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()
3
  • 1
    I placed the file in wp-content/mu-plugins/gallery-owl-shortcode.php and it worked!
    – tgraupmann
    Dec 17, 2015 at 5:47
  • Great 'hack', but do you have any idea why is the css showing in .owl-demo container? #gallery-1 { margin: auto; } #gallery-1 .item { float: left; margin-top: 10px; text-align: center; width: 33%; } #gallery-1 img { border: 2px solid #cfcfcf; } #gallery-1 .gallery-caption { margin-left: 0; } /* see gallery_shortcode() in wp-includes/media.php */
    – dingo_d
    Mar 9, 2016 at 8:28
  • Figured it out. I had to add <style> to: $output = strip_tags($output,'<a><img><span><figcaption><style>');
    – dingo_d
    Mar 9, 2016 at 8:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.