,

Build a jquery feature slider using custom posts

header-custom-posts

Some weeks ago, I wanted to add a slider to my wordpress theme. At first, the slider was reading data from custom meta boxes at posts from the wordpress cms, and was linked to posts, but this had reduced flexibility since it was not possible to link a slider to any post, page or item. The solution? Use custom posts or custom content that is used for the slider only. This tutorial describes how to set up custom post types yourself, and to add a jquery slider that uses these custom post types, both in a wordpress environment. It is assumed that you have basic understanding of wordpress and understand html and css well.

The beginning

Step 1: Adding a Custom Post

With register_post_type, it is possible to register a custom post, which enables you to have another type of posts besides the normal posts that are present in WordPress. The first piece of code need to placed in the functions.php file of your current theme (or any file you use to store the functions of your theme).

add_action( 'init', 'create_post_type_slider_feature' );
	function create_post_type_slider_feature() {
	register_post_type( 'slider_feature',
		array(
		'labels' => array(
                    'name' => _x( 'Slider Items', 'post type general name' ),
                    'menu_name' => __( 'Slider Items' ),
                    'singular_name' => _x('Slider Item', 'post type singular name'),
                    'add_new' => _x('Add New', 'slider_feature'),
                    'add_new_item' => __('Add New Slider Item'),
                    'edit_item' => __('Edit Slider Item'),
                    'new_item' => __('New Slider Item'),
                    'all_items' =>t __('All Slider Items'),
                    'view_item' => __('View Slider Item'),
                    'search_items' => __('Search Slider Items'),
                    'not_found' => __('No Slider Items found'),
                    'not_found_in_trash' => __('No Slider Items found in Trash'),
                    ),
		'public' =>; true,
		'has_archive' =>; false,
		'supports' =>; array('custom-fields','title', 'editor'),
		)
	);
}

This will register a post type called slider_feature, which has a menu header and name ‘Feature Slider Items’, and it is a public (not private)  post. Since this post does not need to be viewed in an archive,’ has_archive’ can be set too false.

“register_post_type registers a custom post type”

 For the slider, we want a title, a box to put the body text of the slider in and some custom fields which allow to add a link and an image for the slider. The values of  ’supports’ allows us to manual enable this options. View the Codex for more information on the register_post_type arguments (there are many options such as add custom categories, custom columns for displaying the post information, etc.)

Enhancing the post

Step 2: Adding custom meta boxes to the Custom Post

Using the following arrays and functions (thanks to Matt Brett & WordPress Codex), it is possible to add custom fields to the custom posts. The following couple of arrays define the 2 custom fields/metabox that are used: one for the image, and one for the url the slider need to link to.

$slider_custom_fields =
array(
	"feature_link" => array(
		"name" => "slider_link",
		"std" => "",
		"title" => "Post or page to link the feature slider item to:"
	),
	"image" => array(
		"name" => "slider_image",
		"std" => "",
		"title" => "Link to feature image:"
	),
);

Now these custom fields need to appear on the the post page as an input text type. The following two functions will deal with that

function slider_custom_fields() {
	global $post, $slider_custom_fields;
	foreach($slider_custom_fields as $meta_box) {
		$meta_box_value = stripslashes(get_post_meta($post->ID, $meta_box['name'].'_value', true));
		if($meta_box_value == "")
			$meta_box_value = $meta_box['std'];
			echo '<p style="margin-bottom:10px;">';
			echo'<input type="hidden" name="'.$meta_box['name'].'_noncename" id="'.$meta_box['name'].'_noncename" value="'.wp_create_nonce( plugin_basename(__FILE__) ).'" />';
			echo'<strong>'.$meta_box['title'].'</strong>';
			echo'<input type="text" name="'.$meta_box['name'].'_value" value="'.attribute_escape($meta_box_value).'" style="width:100%;" /><br />';
			echo '</p>';
			}
	}
function create_meta_box() {
global $theme_name;
		if ( function_exists('add_meta_box') ) {
		add_meta_box( 'new-meta-boxes', 'Slider Settings', 'slider_custom_fields', 'slider_feature', 'normal', 'high' );
		}
	}

As can be seen in the last function the function is used to add metaboxes that are defined by the function slider_custom_fields() and added to post type slider_feature. The data filled in the metaboxes also needs to be saved:

function save_sliderdata( $post_id ) {
	global $post, $slider_custom_fields;
	foreach($slider_custom_fields as $meta_box) {
	// Verify
	if ( !wp_verify_nonce( $_POST[$meta_box['name'].'_noncename'], plugin_basename(__FILE__) )) {
		return $post_id;
	}
	if ( 'page' == $_POST['post_type'] ) {
		if ( !current_user_can( 'edit_page', $post_id ))
		return $post_id;
		}
		else {
			if ( !current_user_can( 'edit_post', $post_id ))
			return $post_id;
			}
		$data = $_POST[$meta_box['name'].'_value'];
		if(get_post_meta($post_id, $meta_box['name'].'_value') == "")
		add_post_meta($post_id, $meta_box['name'].'_value', $data, true);
		elseif($data != get_post_meta($post_id, $meta_box['name'].'_value', true))
		update_post_meta($post_id, $meta_box['name'].'_value', $data);
		elseif($data == "")
		delete_post_meta($post_id, $meta_box['name'].'_value', get_post_meta($post_id, $meta_box['name'].'_value', true));
	}
}

Note: If we want to grab a value of a custom field, we have to use the name of this value + _value added (e.g. get_post_meta(slider_image_value)). Finally we have to add these functions.

add_action('admin_menu', 'create_meta_box');
add_action('save_post', 'save_sliderdata');

That concludes the code that is needed in the functions.php file.

Setting up the slider

Step 3: Querying the posts and retrieving the custom meta boxes

First, download the slider from http://www.slidesjs.com/, which is an excellent slider made by Nathan Searles. The slider used is from the ‘slider with caption’ example, but you only need the slides.min.jquery.js from the js folder and the arrow-next.png, arrow-prev.png, pagination.png and  loading.gif  images from the img folder. Make sure you have the minified javascript of the slider and a link to the jquery library linked in your footer, just before the closing of the body tag, as shown below:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="<?php bloginfo( 'template_directory' ); ?>/js/slides.min.jquery.js"></script>
</body>
</html>

As you can see, I grabbed the jquery from the Google CDN.

Why javascript before body tag?

While javascript is usually placed in the header, in terms of site optimalization it is better to place javascripts in the footer. When placed in the header, the (larger) javascripts will block the loading of all the html elements that are after them, untill they are fully loaded. The disadvantage is that the slider wall appear as the last element, since the javascripts need to be loaded to let the slider appear.

Now place the following part of code in the place were you want the slider to appear, e.g. on index.php.

<div id="sldcontainer">
 <div id="slides">
   <div class="slides-container">
	<?php // Grabs all feature slider posts
    $args = array( 'post_type' => 'slider_feature');
    $loop = new WP_Query( $args );
    while( $loop->have_posts() ) : $loop->the_post();
    ?>
    <div class="slide">
    <?php if( get_post_meta( $post->ID, "slider_image_value", true ) ) : ?>
    <a href="<?php echo get_post_meta( $post->ID, "slider_link_value", true ) ?>" rel="bookmark">
    <img src="<?php echo get_post_meta( $post->ID, "slider_image_value", true ); ?>" alt="<?php the_title(); ?>" />
    </a>
    <?php endif; ?>
    <div class="caption">
     <h2>
      <a href="<?php echo get_post_meta( $post->ID, "slider_link_value", true )?>" rel="bookmark" title="<?php the_title(); ?>">
       <?php the_title(); ?>
      </a>
     </h2>
     <?php the_content() ?>
     <p>
      <a href="<?php echo get_post_meta( $post->ID, "slider_link_value", true ) ?>" title="Continue reading <?php the_title(); ?>" class="read-more">
       More information...
      </a>
     </p>
    </div>
   </div>
   <?php endwhile; ?>
  </div> <!-- #slides-container -->
  <a href="#" class="prev" title="Previous Slide">Previous Slide</a> <a href="#" class="next" title="Next Slide">Next Slide</a>
 </div> <!-- #slides -->
</div><!-- #slidecontainer -->

Now the slides are placed in a slides container, and we can set the $args for the new WP_Query to the post type we want, in this case the slider_feature post type we registered in the first step. Additionaly, we could add more arguments in the $args variable, such as posts_per_page, as shown in the example below (replacement of the old $args):

 $args = array(
	'post_type' => 'msign_feature',
	'posts_per_page' => '10'
 );

In this case, the slider will show a maximum of 10 posts. There are a lot more arguments possible, which e.g. enables to sort the slider posts on a certain kind of manner. More on this can be found in the WordPress Codex. Note that posts_per_page is used instead of the popular showposts, which is deprecated since wordpress 2.1, but still is used in many themes. As you can see in the code, using get_post_meta and the standard tags for the title and content will get the content from what you’ve filled in the dashboard.

The slider settings

Step 4: Javascript values for the slider

Paste the following javascript  just before the closing of the body tag (unless you want the slider appear first, then move it up together with jquery in the head tag). I added this in a seperate functions.js file, but you can also add it in the same document were your slider is, or in your header.php or footer.php of your theme (in the latter cases, don’t forget the script tags!).

$(function(){
	$('#slides').slides({
		container:"slides-container",
		preload: true,
		preloadImage: 'yoururl/img/loading.gif',
		play: 10000,
		pause: 10000,
		slideSpeed: 1250,
		hoverPause: true,
		});
});

The slides will slide with a speed of 1.25 second, when hovered they will pause. I used a value of 10.000 (=10 seconds) for play and pause, so someone has enough time to read the text on your slider. Based on the amount of text you are planning on the slider, you can adjust these values. The effects are applied in the slides within the #slides (ID).

Styling

Step 5: Style the sliders

Without the styling, the sliders will still look crap. But that is going to change with CSS: The following styling will determine the width of the slider and the width, height and position of the caption. It makes the caption semi-transparent, and gives the slides container a subtile box-shadow (these are all CSS 2+ or CSS3 features). I’ll not go any deeper into the css, since the focus is on the custom posts, but this is an indication of what can be made relativily easy.


#sldcontainer {
	width:960px;
	padding:0px;
	margin:0 auto;
	position:relative;
	z-index:0;
    clear:both;
}
#slides {
	box-shadow: 0px 1px 3px #777;
	-webkit-box-shadow: 0px 1px 3px #777;
	-moz-box-shadow: 0px 1px 3px #777;
	position:relative;
	top:0px;
	left:0px;
	z-index:100;
	display:block;
}
/*
Slides container
*/
.slides-container {
	width:960px;
	overflow:hidden;
	position:relative;
	display:none;
}
/*
Each slide
*/
.slides-container div.slide {
	width:960px;
	height:480px;
	display:block;
}
/*
Next/prev buttons
*/
#slides .next,#slides .prev {
	position:absolute;
	top:219px;
	left:-24px;
	background:url(img/arrow-prev.png) no-repeat;
	width:24px;
	height:43px;
	display:block;
	z-index:101;
	text-indent:-10000px;
}
#slides .next {
	background:url(img/arrow-next.png) no-repeat;
	left:960px;
}
/*
Pagination of Slides
*/
.pagination {
	margin:10px auto 0;
	width:100px;
}
.pagination li {
	float:left;
	margin:0 1px;
	list-style:none;
}
.pagination li a {
	display:block;
	width:12px;
	height:0;
	padding-top:12px;
	background:url(img/pagination.png) -60px -25px;
	float:left;
	overflow:hidden;
}
.pagination li.current a {
	background-position:-60px -12px;
}
/*
Caption of Slides
*/
.caption {
	z-index:6;
	position:absolute;
	top:80px;
	left:20px;
	padding:20px;
	background: #000; /*IE FIX */
	background:rgba(0,0,0,0.95);
	width:290px;
	font-size:1.1em;
	color:#fff;
	overflow:hidden;
}
.caption h2 a {
	margin:20px 0 20px 0;
	color:#fff;
	font-size: 1.3em;
}
You finally got it:

Step 6: Finished!

Now, in your wordpress dashboard, you should have the ability to see a new menu called slider items, and you should be able to add sliders, as in the example below from this theme (which will be available for download sooner or later!).

And the edit screen will look like this. A caption does not use many text, but still the editor is used: this makes it easier to upload images for your slider, and paste the url in the custom field for the image.

That’s all! Questions or suggestions? Drop a comment! You can view the demo here:

About Michiel

Michiel is studying a Master in Strategic Product Design and interested in the fields of design, psychology and faith. He became a child of God through Jesus in 2004. He has experience in graphic designing and webdesign, and a degree of industrial design; which enables him to think from the perspective of to user and to solve problems with creativity.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>