I had a request from Dan who asked if I could create a tutorial showing how to use a custom post type along with Nivo Slider and have a custom Meta Box provide the data for it. Well the answer is kind of.

I’m not going to cover how to add a custom post type & a meta box specifically for Nivo Slider. Instead I’m going to show you how to do it in general with hints and tips on how it could be used with Nivo Slider. That way this tutorial is much more useful to everyone, not just those looking to use it with Nivo Slider.

If you are wanting to use Nivo Slider with this tutorial I’ve already covered how to add Nivo Slider into your theme in a previous tutorial. I will not be looking at custom Taxonomies since there is no need for one in this tutorial.

All of this code must be placed in your functions.php file. If you do not have one in your theme, just create a file with that name & you are ready to go. All of these code snippets are PHP so do not forget your opening & closing PHP tags.

Setting Up a Custom Post Type

First let’s set up our post type. I am going to call it ‘Slides’. This part is generally just copy & paste, but it does help if you understand the code a little.

add_action('init', 'add_slides_type');
function add_slides_type()
{
  $labels = array(
    'name' => _x('Slides', 'post type general name'),
    'singular_name' => _x('Slide', 'post type singular name'),
    'add_new' => _x('Add New', 'Post'),
    'add_new_item' => __('Add New Slide'),
    'edit_item' => __('Edit Slide'),
    'new_item' => __('New Slide'),
    'view_item' => __('View Slide'),
    'search_items' => __('Search Slides'),
    'not_found' =>  __('No Slides found'),
    'not_found_in_trash' => __('No Slides found in Trash'),
    'parent_item_colon' => ''
  );
  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => 5,
    'supports' => array('title','editor','author','thumbnail','excerpt','comments','custom-fields','post-formats'),
    'has_archive' => true
  );
  register_post_type('slides',$args);
}

First thing we do here is add an action to run our custom post type function on initialization of WordPress. Next we create the function I just mentioned. The function is made up of three things:

First is an array of labels which you will need to customize with the name you have chosen to give your post type, this should just require a basic knowledge of grammar/languages but you can find an explanation of the labels on the WordPress Codex page for Register Post Type.

Second is an array of arguments. These are also listed on the WordPress Codex page for Register Post Type but this list provided here is generally how you would want them set up provided you don’t need a taxonomy.

Third is the actual call to Register Post Type. All we are doing is giving a unique name for the post type and the array of arguments. Please note that the unique name cannot be more than 20 characters or contain any spaces or capital letters. I’m not sure about special characters although I would assume they cannot be used either.

That should give you your custom post type in your admin menu as shown below.

Slides Post Type Shown In The WordPress Admin

N.B. There is one very important thing you must do after you have created your custom post type. You must visit ‘Settings -> Permalinks’ in your WordPress Admin and hit save. You don’t have the change anything, just hit the save button. This is to refresh your Rewrite Rules or you may have problems accessing your new post type.

Next up we need to create our Meta Box. This is actually the most difficult part of this tutorial & can take a little while to get right.

Creating The Meta Box

The code is quite large so let’s get started. I’m going to go through it in sections, but don’t worry if you want to copy & paste I’ll put the entire code at the end.

add_action( 'add_meta_boxes', 'nivo_add_custom_box' );
add_action( 'save_post', 'nivo_save_postdata' );

First we set up our two actions. The first adds the meta box (WP 3.0+ only) and the second adds a function to the post being saved so we can actually save the data for later use.

function nivo_add_custom_box() {
    add_meta_box(
        'nivo_options',
        'Slide Options',
        'nivo_inner_custom_box',
        'slides'
    );
}

This adds our meta box and also triggers a function to produce the form inside the meta box. The first parameter is a unique name for our meta box, the second a nice name to place in the meta boxes header, the third is the name of the function I mentioned, and finally the slug of the post type you want to attach it to (post, page, custom post type slug).

function nivo_inner_custom_box( $post ) {

  // Use nonce for verification
  wp_nonce_field( plugin_basename( __FILE__ ), 'nivo_noncename' );

  $mydata = get_post_meta($post->ID, 'nivo_slider', TRUE);

  // The actual fields for data entry
  echo '<label for="nivo_imageurl">';
  echo 'URL to image for slide:';
  echo '</label> ';
  echo '<input type="text" id="nivo_imageurl" name="nivo_imageurl" value="'.$mydata['nivo_imageurl'].'" size="25" />';
  echo '<label for="nivo_caption">';
  echo 'URL to image for slide:';
  echo '</label> ';
  echo '<input type="text" id="nivo_caption" name="nivo_caption" value="'.$mydata['nivo_caption'].'" size="25" />';
  //Add more fields as you need them...
}

This function, which is called from add_meta_box via a callback, actually creates the form for you to enter information into. This is all very basic HTML and I am not going to cover it in detail as you may want different fields etc. The ones shown here should be enough to get you started though. The wp_nonce_field function produces a special field that has a one use security code inside, this is used to validate the information when it is saved.

The get_post_meta allows us to grab the information from the database to place back into the field when editing. It makes it a lot easier to use & look a lot better too. The array key to use will always be the same as the input’s name attribute.

function nivo_save_postdata( $post_id ) {

  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
      return;

  if ( !wp_verify_nonce( $_POST['nivo_noncename'], plugin_basename( __FILE__ ) ) )
      return;

  if ( !current_user_can( 'edit_post', $post_id ) )
        return;

  $mydata = array();
  foreach($_POST as $key => $data) {
    if($key == 'nivo_noncename')
      continue;
    if(preg_match('/^nivo/i', $key)) {
      $mydata[$key] = $data;
    }
  }
  update_post_meta($post_id, 'nivo_slider', $mydata);
  return $mydata;
}

This final function saves the data in the meta box when the post is saved. It first checks to see if WordPress is performing an autosave, we don’t want to save our data yet if that is the case. We then check that the one use code is present & still valid. Then we check to see if the user has post editing privledges.

The final part goes through the global post data array and finds all the entries from the submitted meta box pertaining to nivo slider using a preg_match pattern to check the array keys. You can change it to anything you like as long as the field names from the form all have the prefix in common & it is a word/name unlikely to be used by WordPress itself. Inside the preg_match is fairly simple, the forward slashes (/) are just delimiters to contain the pattern we want to match, the caret (^) means starts with, and the letter (i) just means case insensitive. If it’s a match we add it to an array. After that is complete we take the data and give it to update_post_meta which serializes it and places it neatly in the database.

Here is all the code together just in case you need/want to copy & paste it.

add_action( 'add_meta_boxes', 'nivo_add_custom_box' );
add_action( 'save_post', 'nivo_save_postdata' );

function nivo_add_custom_box() {
    add_meta_box(
        'nivo_options',
        'Slide Options',
        'nivo_inner_custom_box',
        'slides'
    );
}

function nivo_inner_custom_box( $post ) {

  // Use nonce for verification
  wp_nonce_field( plugin_basename( __FILE__ ), 'nivo_noncename' );

  $mydata = get_post_meta($post->ID, 'nivo_slider', TRUE);

  // The actual fields for data entry
  echo '<label for="nivo_imageurl">';
  echo 'URL to image for slide:';
  echo '</label> ';
  echo '<input type="text" id="nivo_imageurl" name="nivo_imageurl" value="'.$mydata['nivo_imageurl'].'" size="25" />';
  echo '<label for="nivo_caption">';
  echo 'URL to image for slide:';
  echo '</label> ';
  echo '<input type="text" id="nivo_caption" name="nivo_caption" value="'.$mydata['nivo_caption'].'" size="25" />';
  //Add more fields as you need them...
}

function nivo_save_postdata( $post_id ) {

  if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
      return;

  if ( !wp_verify_nonce( $_POST['nivo_noncename'], plugin_basename( __FILE__ ) ) )
      return;

  if ( !current_user_can( 'edit_post', $post_id ) )
        return;

  $mydata = array();
  foreach($_POST as $key => $data) {
    if($key == 'nivo_noncename')
      continue;
    if(preg_match('/^nivo/i', $key)) {
      $mydata[$key] = $data;
    }
  }
  update_post_meta($post_id, 'nivo_slider', $mydata);
  return $mydata;
}

How Do I Enter Data?

Just like you would a custom field. You should see your new meta box on the add new/edit page for your custom post type just like this.

Just enter the text you want & hit the update/publish button as normal to save it.

How Do I Use The Data?

Using the data is as simple as if you had just used a custom field. In our case it is a little different because the data was stored as a serialized array. To access the data you will need to do something like this before you need access to any of it:

$nivodata = get_post_meta($post->ID, 'nivo_slider', TRUE);

This will store the array into a variable. Then all you need to do is access it as a normal array, like this:

echo $nivodata['nivo_imageurl'];

Again the field names you used in the meta boxes form will be used to access the data so the easier you make them to remember the easier it will be to write the code.

Like I said this tutorial is aimed at anyone wanting to create a custom post type or custom meta box. However if you want to add custom captions you will need to visit the Nivo Slider Custom Captions tutorial and follow the section for Custom Fields. The exception is that the variable $caption would end up an array and would need to change to $caption['blah_blahblah'] where ‘blah_blahblah’ is the field name you used to contain your caption inside your custom meta box.

Hopefully this tutorial has helped show how to add a custom post type with a custom meta box. I didn’t want it to become Nivo Slider specific as it is useful to so many other people too. If you are using this tutorial for Nivo and you are stuck with anything please leave a comment & I’ll help you out. I will be making another tutorial in the next few days to extend this one detailing how to use the post meta data with Nivo Slider as it is worthy of it’s own tutorial, until then please use this one to make your post type & meta box as I won’t be repeating it in that new tutorial.