Random home page background images with caption text

First of all I don’t think that create a custom post type only for backgrounds is a right choose: backgrond are images and images already have their post type: attachment.

If you have Worpress 3.5+ you can register a custom taxonomy for attachments, call it, e.g. ‘image_scope’ :

register_taxonomy('image_scope', 'attachment', $args );

for the $args array see the codex, but ensure you have

  • $args['public'] = true
  • $args['show_ui'] = true
  • $args['show_admin_column'] = true
  • $args['update_count_callback'] = '_update_generic_term_count'

In your media manager you will set this taxonomy to a specific term, fo example ‘ background’.

Now, in your template file, you can use a custom wp_query, using tax_query to select only backgrounds with the taxonomy image_scope setted to ‘background’:

$args = array(
  'post_type' => 'attachment',
  'post_status' => 'inherit',
  'posts_per_page' => -1,
  'orderby' => 'rand',
  'tax_query' => array(
      array(
        'taxonomy' => 'image_scope',
        'field' => 'slug',
        'terms' => 'background'
      )
  );
);
$bg_query = new WP_Query( $args );

As you can see, the order is already randomized, so when you print it on the template you don’t need to randomize via js.

So in the template you will have, after the query:

if ( $bg_query->have_posts() ) :
  echo '<div id="full-bg">';
  $i = -1;
  while( $bg_query->have_posts() ) :
    $i++;
    $bg_query->the_post();
    $url = wp_get_attachment_url( get_the_ID() );
    $class = $i == 0 ? 'full-bg active' : 'full-bg';
?>
<img class="<?php echo $class; ?>" src="https://wordpress.stackexchange.com/questions/107554/<?php echo $url; ?>" alt="<?php the_title; ?>" data-desc="<?php the_excerpt(); ?>" />
<?php
endwhile;
echo '</div>';
endif;
wp_reset_postdata();
?>

And the javascript:

jQuery(document).ready(function($) {

function handle_active() {
  var $active = $("#full-bg img.active");
  var title = $active.attr('alt');
  var desc = $active.data('desc');
  alert('Active title is' + title + ' and active description is ' + desc);
}

setInterval(function(){
  var $active = $("#full-bg img.active");
  $active.animate( {opacity:0}, 500, function(){
    $(this).removeClass('active');
  });
  if( $active.next('img').length > 0 ) {
    $active.next('img').addClass('active').animate( {opacity:1}, 500, function() {
      handle_active();
   });
  } else {
    $('#full-bg img').eq(0).addClass('active').animate( {opacity:1}, 500, function() {
      handle_active();
   });
  }
}, 4000);

handle_active();

}

Of course change the handle_active() function to fit your needs.

Hope it helps, but please note that the code is not tested and I’m not a js developer…