Skip to content
Daniel Shaw · WordPress & WooCommerce Developer Wellington, New Zealand

👋 Not available for new client work right now!

Simple slider for WordPress Post Types with Transients

I've been using the Transients API on a more regular basis recently, what with Optimise! in the wind so much right now. Here's a short & sweet approach to creating and caching an image slider for a WordPress post, page or custom post type.

For this example, the result would be an image slider with thumbnail pagination (per the layout here).


bxSlider is a really great script that comes with a lot of helper options built-in. The markup is a simple unordered list containing images, with a class on the <ul> tag.

Super-flexible situation.

The bundled CSS can be trimmed substantially—obviously this depends on your particular configuration—and, once done, it can be dropped into style.css to avoid an additional script link.

For JS dependencies on WordPress sites you are best served linking javascript files via the wp_register_script (for scripts with handles pre-registered in WordPress, only) and wp_enqueue_script functions. So, for bxSlider:

function the_js() { if ( !is_admin() ) { wp_register_script( 'jquery' ); wp_enqueue_script( 'bx-slider', get_template_directory_uri() . '/js/jquery.bxslider.min.js', array( 'jquery-core' ), 4.1.2, true ); } } add_action( 'wp_enqueue_scripts', 'the_js' );

Lastly, call the slider via the <ul> class:

jQuery(document).ready(function($) { $('.bx-slider').bxSlider(); } );

Image bank

The way I typically use this, the images are all stored as attachments to the current page. For the client, it's then just a case of uploading an image via the post Media Uploader in order to create or add to a slider.1

To control the output and avoid image dimension insanity2, set up some resizing rules with add_image_size.

if ( function_exists( 'add_image_size' ) ) { add_image_size( 'bx-slide', 500, 500, true ); add_image_size( 'bx-slide-pager', 75, 75, true ); }

The above will create two additional images per uploaded image, one for the slider and one for its corresponding pagination thumbnail.

All together now

To pull the post images into the slider use get_children. This will output an array which can then be looped through to grab each image:

$images = get_children( array( 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order' ) ); foreach ( $images as $image ) { $img = wp_get_attachment_image ( $image->ID, 'bx-slide', false, array( 'alt' => 'Something alty' ) ); echo $img; } // Output: <img src="" alt="Something alty" />

The important part is the second argument of wp_get_attachment_image: bx-slide. This references the resized images defined earlier with add_image_size and ensures a correctly proportioned image is used.

A couple of useful things to note:

  1. setting 'orderby' => 'menu_order' as an argument of get_children allows the slider image order to be manipulated via the drag-and-drop Media Uploader panel
  2. you can add additional attributes to the <img> element with an optional array as the fourth argument of wp_get_attachment_image().

At this point, it's just a case of wrapping everything with the bxSlider markup to unlock and achieve your image slider badge.



function slide_images() { global $post; $is_transient = 'slide_images_' . $post->ID;3 $slide_images = get_transient( $is_transient ); if ( false === $slide_images ) { ob_start(); $images = get_children( array( 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order' ) ); echo '<ul class="bx-slider">'; foreach ( $images as $image ) { $img = wp_get_attachment_image( $image->ID, 'bx-slide', false, array( 'alt' => get_the_title() ) ); echo '<li>' . $img . '</li>'; } echo '</ul>'; echo '<div id="bx-pager">'; $count = 0; foreach ( $images as $image_thumb ) { $thumb = wp_get_attachment_image( $image_thumb->ID, 'bx-slide-pager', false ); echo '<a data-slide-index="' . $count . '" href="">' . $thumb . '</a>'; $count++; } echo '</div>'; $slide_images = ob_get_contents(); ob_end_clean(); set_transient( $is_transient, $slide_images, 60*60 ); } echo $slide_images; }

We are:

  • setting a unique name for the transient by appending a unique value (the post ID) to a prefix
  • checking to see if a transient for this post type object already exists
  • if a transient exists go to the last line
  • if there is no transient, run the query
  • set the output of the query in a transient
  • output the transient

The third argument of set_transient(), "60*60", specifies how long a transient should persist. In this case it will expire after one hour (60 x 60 seconds). Once a transient has expired a new one will be created when the page is next visited.

Back on your page, you just need to call slide_images()

<?php slide_images(); ?>

…and your slider will display.

Clearing the cache

As soon as your slider displays in a browser for the first time, it will be cached. However, you may need to make a change—for example, add a new image—and want to see the result without waiting for the transient to expire. In this case, just hook delete_transient() into the save_post action, as so:

function slide_images_clear() { delete_transient( 'slide_images_' . $post->ID ); } add_action( 'save_post', 'slide_images_clear' );

With the above in place, whenever content is saved the associated transient will be expired.

  1. So, caveat: if there's a requirement for images on a page other than those to be included in the slider, there'll need to be additional filtering for "slider only" images going on.
  2. The most amazing I've seen so far was a client-uploaded image with a 1:20 ratio.
  3. Don't forget to title your transients!