Create and Manage a Nivo Slider using WordPress Custom Post Types

Let’s say that you want to create a standalone Nivo Slider on a WordPress powered site. You have a couple of options. You can always purchase and download the Nivo WordPress plugin. I know lots of developers that have purchased and used this plugin with great success. The price of the plugin is only $20 USD. The point of this tutorial is not to save $20. There are actually some pretty cool features in the Nivo WordPress plugin, like using short tags to create sliders on any post or page. The point of this tutorial is to create a Nivo slider on your site and store the slider content as a Custom Post Type (CPT).

Creating and maintaining your Nivo slider as a CPT will give you a bit more flexibility down the road. For example, let’s say that a brand new jQuery slider plugin is released and you want to switch. Since the slider content is saved as a CPT and not tied to a plugin, then you could easily switch out the Nivo jQuery plugin with the alternative jQuery slider plugin. Think of this tutorial as a future proofed approach.

Step 1: Set Up the Custom Post Type

I’m going to use generateWP to generate the CPT code that will be copied and pasted into the functions.php file in your theme folder. It should look something like this, however, it could look different based upon your needs:

// Register Custom Post Type
function homepage_slider() {
	$labels = array(
		'name'                => _x( 'Slides', 'Post Type General Name', 'text_domain' ),
		'singular_name'       => _x( 'Slide', 'Post Type Singular Name', 'text_domain' ),
		'menu_name'           => __( 'Homepage Slider', 'text_domain' ),
		'parent_item_colon'   => __( 'Parent Slide:', 'text_domain' ),
		'all_items'           => __( 'All Slides', 'text_domain' ),
		'view_item'           => __( 'View Slide', 'text_domain' ),
		'add_new_item'        => __( 'Add New Slide', 'text_domain' ),
		'add_new'             => __( 'New Slide', 'text_domain' ),
		'edit_item'           => __( 'Edit Slide', 'text_domain' ),
		'update_item'         => __( 'Update Slide', 'text_domain' ),
		'search_items'        => __( 'Search slides', 'text_domain' ),
		'not_found'           => __( 'No slides found', 'text_domain' ),
		'not_found_in_trash'  => __( 'No slides found in Trash', 'text_domain' ),
	);

	$args = array(
		'label'               => __( 'homepage_slider', 'text_domain' ),
		'description'         => __( 'Homepage Slides', 'text_domain' ),
		'labels'              => $labels,
		'supports'            => array( 'title', 'editor', 'thumbnail', 'page-attributes', 'custom-fields' ),
		'taxonomies'          => array( 'category', 'post_tag' ),
		'hierarchical'        => false,
		'public'              => true,
		'show_ui'             => true,
		'show_in_menu'        => true,
		'show_in_nav_menus'   => false,
		'show_in_admin_bar'   => true,
		'menu_position'       => 20,
		'menu_icon'           => '',
		'can_export'          => false,
		'has_archive'         => false,
		'exclude_from_search' => true,
		'publicly_queryable'  => true,
		'capability_type'     => 'post',
	);

	register_post_type( 'homepage_slider', $args );
}

// Hook into the 'init' action
add_action( 'init', 'homepage_slider', 0 );

Your CPT function might look a little different. The basic functionality included for this tutorial are ‘thumbnails’ (a.k.a Featured Image), ‘page-attributes’ (to order slide rotation by menu order) and ‘custom-fields’ (to enter a target link for the slide).

Step 2: Enable Featured Images in your functions file

This is an easy step. In order to upload an image to our custom post type, we have make sure that featured images are enabled. We also are going to set up the image size as well. Let’s say that our slider image needs to be 800 x 450. We would set that up in the functions.php file like this:

//Add Featured Image Function
add_theme_support( 'post-thumbnails' );

//Add additional generated image sizes
add_image_size( 'homepage-slide', 800, 450, true ); //(cropped)

This code snippet will make sure the slide images being uploaded are automatically resized to the exact size.

Step 3: Add Slides

We need to add some slides before we add the PHP, HTML and jQuery. In your WordPress Dashboard, hover over the Homepage Slider tab on the left and select “Add New”.

Make sure that you can see “Custom Fields” toward the bottom of the page. If you don’t, then click “Screen Options” in the top right of the page and make sure the “Custom Fields” box is ticked.

Give the post a Title, some content in the WYSIWYG and a featured image. In the “Custom Fields” area, set the “Name” as slide_target_link and the “Value” field should be a link that starts with http:// or https://. For example, if the slide is suppose to link to a page or post within your site, navigate to that page or post, copy the url in the browser address bar, and then paste it into the “slide_target_link” Value field. You could also paste in a url that is not on your site.

Please make sure that you create at least two slides.

Step 4: Include the Nivo jQuery Plugin

Download the Nivo jQuery plugin from their download page. Copy the jquery.nivo.slider.pack.js file to your theme folder. Next open up your functions.php file, then copy and paste the following code snippet into your functions.php file:

//Inject Theme Dependent jQuery plugins

function my_scripts_method() {

	if (is_front_page()) {   

		// register your script location, dependencies and version
			wp_register_script('nivo-library',
			get_template_directory_uri() . 'jquery.nivo.slider.pack.js',
			array('jquery'),
			'3.2' );

		// enqueue the script
		wp_enqueue_script('nivo-library');
	}

}

add_action('wp_enqueue_scripts', 'my_scripts_method');

There are two things you might want to change in the previous snippet. The location of the “jquery.nivo.slider.pack.js” file and is_front_page conditional statement. In this example, the Nivo library is only included on the front page of the site.

Next we need to include the jQuery code to activate the Nivo Slider. The code snippet should be added right before the </body> tag and look something like this:

<?php if ( is_front_page() ) : ?>
<script type="text/javascript">

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

          $('#slider').nivoSlider({
	       effect: 'fade',
	       animSpeed: 250, // Slide transition speed
	       pauseTime: 9000 // How long each slide will show	
	   });

});
</script>
<?php endif; ?>

There are TONS of extra Nivo options that you can include.

Step 5: Include Nivo CSS files

This is an easy step. Make sure you include the main Nivo CSS file. You will want to include the Nivo Theme CSS file if you are using one. If you want to include these CSS files on the front page, then set up the CSS call something like this:

<?php if ( is_front_page() ) : ?>
<link rel="stylesheet" href="<?php bloginfo('template_directory'); ?>/library/styles/nivo-slider.css" type="text/css" media="screen" />
<link rel="stylesheet" href="<?php bloginfo('template_directory'); ?>/library/styles/nivo-theme.css" type="text/css" media="screen" />
<?php endif; ?>

Step 6: Set Up the PHP and HTML

This is a simple PHP example to demonstrate basic functionality. Here a code snippet that sets up a rotating image as well as a rotating HTML block. The post title is used as the slide <h3> tag, the post content is the slide’s <p> tag, the featured image is the slide image and the slide_target_link is the link for the <h3> tag as well as the slide image.

<div class="slider-wrapper">

	<div id="slider" class="nivoSlider default-theme">
	
		<?php $slider_query = new WP_Query( array ( 'post_type' => 'homepage_slider', 'posts_per_page' => '7', 'orderby' => 'menu_order', 'order' => 'ASC' ) ); ?>

		<?php if ($slider_query->have_posts()) : while ($slider_query->have_posts()) : $slider_query->the_post(); ?>

			<?php 

				$slider_img_src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'homepage-slide', false, '' ); 
				$target_link = get_post_meta(get_the_ID(), 'slide_target_link', true);
           ?>

	            <a href="<?php echo $target_link; ?>"><img src="<?php echo $slider_img_src[0] ?>" width="<?php echo $slider_img_src[1] ?>" height="<?php echo $slider_img_src[2] ?>" alt="<?php the_title_attribute(); ?>" title="#htmlcaption-<?php the_ID();?>" /></a>

          <?php endwhile; else: endif;  ?>

      </div>

</div>

     <?php if ($slider_query->have_posts()) : while ($slider_query->have_posts()) : $slider_query->the_post(); ?>

     	<?php $target_link = get_post_meta(get_the_ID(), 'slide_target_link', true); ?>

			<div id="htmlcaption-<?php the_ID(); ?>" class="nivo-html-caption">

				<h2><a href="<?php echo $target_link; ?>"><?php the_title(); ?></a></h2>

					<?php the_content(); ?>

			</div>

		<?php endwhile; else: endif; ?>

This code snippet uses two Loops. One for the image files. And one for the HTML text blocks. I know this isn’t the best solution, however, the Nivo slider requires the images and HTML text blocks to be separated in the HTML. In this example, I’m using the post ID of the slide to match up the images to the HTML text blocks.

Please note that you are going to want to work with the CSS to get the layout that you want.

45 thoughts to “Create and Manage a Nivo Slider using WordPress Custom Post Types”

  1. This works perfectly on the homepage, but whenever I copy the exact same code in a category page it doesn’t work.
    I have 3 sliders, 2 of them work on every page, the last one only works in the homepage.
    Any ideas?

    1. Try erasing lines 5 and 15 from Step 4. So instead of:

      //Inject Theme Dependent jQuery plugins
      
      function my_scripts_method() {
      
      	if (is_front_page()) {   
      
      		// register your script location, dependencies and version
      			wp_register_script('nivo-library',
      			get_template_directory_uri() . 'jquery.nivo.slider.pack.js',
      			array('jquery'),
      			'3.2' );
      
      		// enqueue the script
      		wp_enqueue_script('nivo-library');
      	}
      
      }
      
      add_action('wp_enqueue_scripts', 'my_scripts_method');
      

      It should look like:

      //Inject Theme Dependent jQuery plugins
      
      function my_scripts_method() {
      
        
      
      		// register your script location, dependencies and version
      			wp_register_script('nivo-library',
      			get_template_directory_uri() . 'jquery.nivo.slider.pack.js',
      			array('jquery'),
      			'3.2' );
      
      		// enqueue the script
      		wp_enqueue_script('nivo-library');
      	
      
      }
      
      add_action('wp_enqueue_scripts', 'my_scripts_method');
      
  2. Hi,
    This is awesome. It’s working Perfectly.
    Can I create a Setting Page inside the WP Admin Office to manage the slider Speed,Transition and effects ?
    If possible so it’ll be magic for me now.

    Thank You,
    Som

  3. Hi, Thank you for nice tutorial. I’m just wondering about the $slide_target… how could i set custom link for each slide?

    Thanks

  4. This was so simple and worked perfectly! You did a great job. So easy to follow and understand. Thank you so very much! It was such a bit help!

  5. Great tut. I have tried to get this work multiple times. This is the first tutorial that worked seamlessly. Thanks so much!

  6. Please disregard my previous question. I had laid a frame over the slider and that was causing the problem. I should have checked that first.

  7. I’m just about done with the install of your code. You’ve done a great job with this! I have one last thing I’m struggling with. I can’t get the nivo-caption to respond as an a link. In my developer tools I’m seeing multiple layers of “a href” being called and I think that may be causing it. Did you ever resolve the two loops issue? Let me know if you have any tips.

  8. Hey…thanks a lot for this post…you’re just great!!
    I´ve benn working with the nivo slider setting the post as categories for query_post, but was unable to get the caption working for each of the slider becouse the caption was outside the div of the slider image
    This way made the work easier and your post is so simple to understand….thanks again
    Eres un máquina!

  9. Pingback: How to call Shortcode categories for custom post types? - WordPress BuddyPress Tweaks
  10. Hi again Will,
    Here’s my attempt at merging some of your shortcode some category code 🙂

    Unfortunately it only appears to show one slide. Maybe you can spot where I’ve gone wrong

    //Add Nivo Short Codes
    function nivo_slider_function($atts){
       
       extract(shortcode_atts(array(
          'posts' => 5,
    	  'category' => ''
       ), $atts));
    
     $args = array(
            'numberposts' => -1,
            'orderby' => 'menu_order',
            'order' => 'ASC',
            'post_type' => 'homepage_slider'
        );
    
        if ( ! empty( $category ) ) {
            $args['category_name'] = $category;
        }
    
        $posts = get_posts( $args );
    
        $homepage_slider  = ''; //Open the container
        foreach ( $posts as $post ) { // Generate the markup for each Question
            $homepage_slider .= sprintf(('%1$s%2$s'),
                $post->post_title,
                wpautop($post->post_content)
            );
        }
        $homepage_slider .= ''; //Close the container
    	
    	
       $return_string = '';
       
       query_posts(array('post_type' => 'homepage_slider', 'orderby' => 'menu_order', 'order' => 'ASC' , 'showposts' => $posts));
       
       if (have_posts()) :
          while (have_posts()) : the_post();
          
         	 $slider_img_src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'homepage-slide', false);
    	     $target_link = get_post_meta(get_the_ID(), 'slide_target_link', true);   
             $return_string .= '';
          
          endwhile;
       endif;
       $return_string .= '';
    
       wp_reset_query();
       return $return_string;
       
    }
    
    function register_shortcodes(){
       add_shortcode('slider-demo', 'nivo_slider_function');
    }
    
    add_action( 'init', 'register_shortcodes');
    
    1. Hey Judith! Sorry I haven’t gotten back to you quicker, but my personal life is mad crazy in a very good way right now. I will have some time this weekend to look this over and see if I can help you out.

      Thanks!

      1. Hey Judith!

        I think there might be something with line 20 in your code. I believe you might be overwriting the $posts variable that is captured in line 5 and later used in line 34 to define the amount of queried slides.

  11. Ok I’ve got it working 🙂

    Even added your shortcode function.
    Although that seems to have removed the theme-default styles, which I suppose are easily fixed with a bit of css

    I agree with all the other comments it would be nice to add different slideshows activated through to categories.
    I shall have a crack at the Taxonomies post.

    Thanks
    Judi

  12. Hi Will,
    I love your tutorial
    I’m trying to implement it in a twenty twlve child theme, but just can’t get it to work.
    Everything appears to have joined up correctly but I don’t understand what to put instead of is_front_page if I want the slideshow in any page or where to put the html/php for the slider. I guess I might need a shortcode too?

    I created a stand alone template and applied that to a page but the function appears to have duplicated the slider titles and when I click next image itself is duplicated twice too.

    Am I doing something wrong? Sorry I’m a bit of a novice at php 🙂

    Do you have an example on github?

    Thanks for all your help

  13. I’m trying to use this tutorial on this portfolio page:
    I’m having trouble with the featured image size. My image is blowing up to be larger than it’s normal size and I’m not sure why.

    Also, once I get the featured image size fixed I’m going to try to set up the slider to work with each category. So there will be one portfolio page and a list of categories to the left of the featured image. When you choose a category that will trigger a different set of scrollable images in the featured image location. Do you know how to set something like this up?

    Thanks!

  14. Hi WIll,

    Tutorial is great thanks. Just wondered if you can tell me how I can add the slider to different pages, and not just the front page?
    Also, is there a way of adding different slides to different pages?

    Thanks
    Vicky

    1. Hey, it sounds like you might want to take advantage of the WordPress shortcode. I would start by looking over this comment thread.There are a few good code snippets in there that will help you generate the shortcode.

      I would also really advise you read the shortcode section on the WordPress codex, since it will have a ton of valuable background.

      It is possible to show different sliders on different pages. I would probably modify the short code to include an argument for pulling in a specific post ID. This is really easy, but please let me know if you need help!

  15. Hey there! This is the best tutorial i’ve found so far, i’m new to wordpress themes and recently started making my own, but I think i’m having some issues with Java like Chris at the top. I guess the difference from me and him is that i’m still too new to this to see the mistake 🙁

    Any help is appreciated!

    – Fred

    1. Nevermind I actually fixed it! I intergrated my java with a different function and commented out the one you made.

      Now I just have to figure out how to change the nav control from numbers to bullets :)! Thanks a lot for the tut!

      – Fred

      —– My fix ——

      I commented this one out:

      function my_scripts_method() {

      if (is_front_page()) {

      // register your script location, dependencies and version
      wp_register_script(‘nivo-library’,
      get_template_directory_uri() . ‘jquery.nivo.slider.pack.js’,
      array(‘jquery’),
      ‘3.2’ );

      // enqueue the script
      wp_enqueue_script(‘nivo-library’);
      }

      }
      add_action(‘wp_enqueue_scripts’, ‘my_scripts_method’);

      And used this one instead:

      function mr_css_and_js_for_slider() {
      wp_enqueue_script( ‘jquery’ );
      wp_enqueue_script( ‘nivosliderjs’, get_stylesheet_directory_uri() . ‘/jquery.nivo.slider.pack.js’, array(‘jquery’), null, true );
      }
      add_action( ‘wp_enqueue_scripts’, ‘mr_css_and_js_for_slider’ );

  16. Will,

    You’re far too kind. This tutorial saved me hours of puzzling how to put together a easy slider for my client.

    At first your code was not working for me. I realized there were a couple of extra brackets between the ‘add action’ statements in Step 4. Once I took them out everything started working smoothly.

    Thanks again!

  17. ues i am trying to add categories to homepage_slide. this step i now how to do. but i need help with next… i want to show slider by categories id.
    for example category name (cars) have 7 slides (posts with images and text) and cat id=5. so i want to insert shortcodes in post or page with category id (5) and it will show cars slider. or insert the code to php file.

    thanks

  18. Hello Will Rees, thanks for the great totorial. i have one quasion, how can i add categories? i want to create different slides and add them to different categories. them to show all slides based on category. thanks for help!

  19. This is phenomenal and exactly what I’ve been looking for. It worked great from the beginning. Would you have any idea how to turn this into a short code?

    I’m doing a parallax theme and I prefer the CTP over the actually plugin. If I can figure out the “short code” version of it by using the last section as function thats echoing those elements. Thats where I am getting stuck.

    Any ideas?

    1. Hey. Creating the short code should be pretty easy. I would look at the short code generator at http://generatewp.com/ as a place to start. They have some examples of short code. If you look at the Samples section of the short code generator, then select Recent Posts. It will generate a code snippet for you that is going to be a solid place to start. If you want to share what you create, then I would be glad to look at it and make any suggestions, but I’m sure it will be awesome.

      Thanks for the comment!

      1. Hey Will.

        What are you thoughts on the this?

        // Add Shortcode
        function slider_shortcode( $atts , $content = null ) {

        // Attributes
        extract( shortcode_atts(
        array(
        ‘posts’ => ‘5’,
        ‘id’ => ”,
        ‘width’ => ”,
        ‘height’ => ”,
        ), $atts )
        );

        // Code
        $output = ”;//#sliderwrap
        $output = ”;//#slider
        query_posts(‘post_type=homepage_slider&posts_per_page=7&orderby=menu_order&order=ASC’); //posttype
        if (have_posts()) : while (have_posts()) : the_post();
        $the_query->the_post();
        $slider_img_src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), ‘homepage-slide’, false, ” );
        $target_link = get_post_meta(get_the_ID(), ‘slide_target_link’, true);
        return ”; //sliderimage
        endwhile; else: endif;
        wp_reset_postdata();
        $output = ”;//#slider-close
        $output = ”;//#sliderwrap-close
        return $output;

        }
        add_shortcode( ‘slider’, ‘slider_shortcode’ );

        1. Hey man, I whipped this up for you. I’m not sure if it’s 100% going to fit your needs, but it should be easy to modify. I’ve tested the the functionality so it should be good to go.

          function nivo_slider_function($atts){
             
             extract(shortcode_atts(array(
                'posts' => 5,
             ), $atts));
          
             $return_string = '
          '; query_posts(array('post_type' => 'homepage_slider', 'orderby' => 'menu_order', 'order' => 'ASC' , 'showposts' => $posts)); if (have_posts()) : while (have_posts()) : the_post(); $slider_img_src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'homepage-slide', false); $target_link = get_post_meta(get_the_ID(), 'slide_target_link', true); $return_string .= ''; endwhile; endif; $return_string .= '
          '; wp_reset_query(); return $return_string; } function register_shortcodes(){ add_shortcode('slider-demo', 'nivo_slider_function'); } add_action( 'init', 'register_shortcodes');
          1. This is awesome. Completely works. Would you by chance know how to not allow the content to appear, just the feature image?

            Also if you have a pay pal account send me the info so I can buy you a beer

            1. This should remove any text that is showing up on the slides. If you would like to buy me a beer, my PayPal is rees.will@gmail.com. Thanks!

              function nivo_slider_function($atts){
                 
                 extract(shortcode_atts(array(
                    'posts' => 5,
                 ), $atts));
              
                 $return_string = '
              '; query_posts(array('post_type' => 'homepage_slider', 'orderby' => 'menu_order', 'order' => 'ASC' , 'showposts' => $posts)); if (have_posts()) : while (have_posts()) : the_post(); $slider_img_src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'homepage-slide', false); $target_link = get_post_meta(get_the_ID(), 'slide_target_link', true); $return_string .= ''; endwhile; endif; $return_string .= '
              '; wp_reset_query(); return $return_string; } function register_shortcodes(){ add_shortcode('slider-demo', 'nivo_slider_function'); } add_action( 'init', 'register_shortcodes');
  20. Hi, I’m new to creating wordpress themes, and I’m trying to make one with a nivo slider on the homepage. I have followed your instructions, and it displays the first image perfectly, but the slideshow wont start. Is it likely that the .js file is not correctly linked? I thought that might be the problem, so I used inspect element and found the file under the resources tab had an error. It reads:

    Uncaught Type Error: Object# has no method ‘on’

    and another that says:

    Uncaught Type Error: undefined is not a function (repeated 12 times)

    any idea what that could mean? I copied the file directly from my download from the nivo slider site.

    I would give you a link to the site, but I’m working locally on my computer. This method is perfect for how I want to use the Nivo Slider on my site, and it looks great, I just can’t get it running. Let me know if you have any ideas I could try.
    Thanks,
    Chris

    1. That sounds like a jQuery issue to me. How are you including jQuery in your theme? What version of jQuery is being included?

      1. Ack! you were right. I’m building this theme using an old tutorial, and the jquery they linked up was an old version. Got it working now. Thanks!!

  21. Wow. Like, a zillion thanks. I mapped out how I wanted to make nivo work for a site, then started searching around to cobble together a solution. The final result worked at about 80% of my desire (and annoyed me, because it didn’t use custom posts). With a bit of tweaking, this did exactly what I wanted. Beautiful. So, add a few more thanks to those initial zillion.

Leave a Reply

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