WordPress 3.5 has a very nice photo new gallery UI, and because I’m the kind of guy who just can’t be happy with nice, I had to go and hack it to make it run a slide show by default.
If you’re a wordpress.com user, you already have the slideshow feature – and I’ll bet money that it’s a damn sight more refined than mine – but for those of us running our own sites, here’s all you need to create simple, straighforward slideshows using any size of image:
1) Paste this into your functions.php file:
function slide_gallery_shortcode($foo, $attr) { global $post; static $instance = 0; $instance++; // We're trusting author input, so let's at least make sure it looks like a valid orderby statement if ( isset( $attr['orderby'] ) ) { $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] ); if ( !$attr['orderby'] ) unset( $attr['orderby'] ); } extract(shortcode_atts(array( 'order' => 'ASC', 'orderby' => 'menu_order ID', 'id' => $post->ID, 'itemtag' => 'dl', 'icontag' => 'dt', 'captiontag' => 'dd', 'columns' => 1, 'size' => 'full', 'include' => '', 'exclude' => '' ), $attr)); $columns = 1; $size = 'full'; $id = intval($id); if ( 'RAND' == $order ) $orderby = 'none'; if ( !empty($include) ) { $include = preg_replace( '/[^0-9,]+/', '', $include ); $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); $attachments = array(); foreach ( $_attachments as $key => $val ) { $attachments[$val->ID] = $_attachments[$key]; } } elseif ( !empty($exclude) ) { $exclude = preg_replace( '/[^0-9,]+/', '', $exclude ); $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); } else { $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); } if ( empty($attachments) ) return ''; if ( is_feed() ) { $output = "\n"; foreach ( $attachments as $att_id => $attachment ) $output .= wp_get_attachment_link($att_id, $size, true) . "\n"; return $output; } $itemtag = tag_escape($itemtag); $captiontag = tag_escape($captiontag); $columns = intval($columns); $itemwidth = $columns > 0 ? floor(100/$columns) : 100; $float = is_rtl() ? 'right' : 'left'; $selector = "gallery-{$instance}"; $gallery_style = $gallery_div = ''; $size_class = sanitize_html_class( $size ); $gallery_div = ""; $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div ); $i = 0; foreach ( $attachments as $id => $attachment ) { $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false); $output .= "<{$itemtag} class='gallery-item'>"; $output .= " <{$icontag} class='gallery-icon'> $link {$icontag}>"; if ( $captiontag && trim($attachment->post_excerpt) ) { $output .= " <{$captiontag} class='wp-caption-text gallery-caption'> " . wptexturize($attachment->post_excerpt) . " {$captiontag}>"; } $output .= "{$itemtag}>"; } $output .= "\n"; return $output; } add_filter('post_gallery', 'slide_gallery_shortcode', 4, 2);
This is just a hacked version of the gallery shortcode handler from WordPress’ media.php file. All I do is reset a few defaults and remove some default CSS that messes with how I want it to look.
2) Create a new javascript file:
// Milliseconds, obviously. var initial_fade_in = 500; var fade_in_time = 1000; var fade_out_time = 1000; var slide_interval = 10000; var running = true; $(document).ready(function() { $('DIV.gallery dl:first').animate({opacity: 1.0}, initial_fade_in); $('DIV.gallery dl:first').addClass('active'); // Optionally, you can create a 'Next' element (graphic, button, whatever) // and place it anywhere inside the 'gallery' div. $('DIV.gallery').hover(function (){ $(this).css('opacity', '0.9'); $('.gallery #next').fadeIn(); running = false; }, function(){ $(this).css('opacity', '1.0'); $('.gallery #next').fadeOut(); running = true; }); $('.gallery #next a').hover(function(){ running = false; }, function (){ running = true; }); $('.gallery #next a').click(function(){ running = true; next_slide(); running = false; return false; }); }); function next_slide() { if (!running){ return; } var $active = $('.gallery dl.gallery-item.active').length ? $('.gallery dl.gallery-item.active') : $('.gallery dl.gallery-item:last'); var next = 0; $next = $active.next('dl').length ? $active.next('dl') : $('.gallery dl:first'); $active.addClass('last-active'); // Some browsers do funny things with JQuery animate if the element being manipulated // isn't at least notionally on the page. Use 'opacity: 0' instead of 'display: none' // as the initial state. $next.css({opacity: 0.0}) .animate({opacity: 1.0}, fade_in_time, function() { $('div.gallery dl.last-active').animate({opacity:0}, fade_out_time, function(){ $('div.gallery dl.last-active').removeClass('active last-active'); }); }) .addClass('active'); } $(function() { setInterval( "next_slide()", slide_interval ); });
2a) Add the necessary links to your header.php file:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/wp-slideshow.js"></script> <!-- or whatever you've name it... -->
3) Add some CSS styling:
Needless to say, you’ll want to customise the colours:
/* Gallery slide show styles */ .gallery { position:relative; top: 0px; left: 0px; min-height: 800px; background: transparent; } .gallery dl { position:absolute; top:250; left:250; margin-left: 1em; z-index:8; opacity:0.0; } gallery dl.active { z-index:10; opacity:1.0; border: 1px solid #c6c6c6; } .gallery dl.last-active { z-index:9; } dd.gallery-caption { color: #fff; border: 1px solid #c6c6c6; border-bottom: 1px solid #000; background: #000; opacity: 0.6; height: 3em; margin: 0; margin-top: -3em; padding: 1em; text-align: left; text-shadow: 1px 1px 1px #000; font-size: 10pt; font-weight: normal; font-family: 'helvetica neue',helvetica,sans-serif; } dd.gallery-caption a { color: #68a; }