A Guide to WordPress Custom Post Types: Creation, Display and Meta Boxes

A Guide to WordPress Custom Post Types: Creation, Display and Meta Boxes

Tutorial Details
  • Program: WordPress
  • Version: 3.3 and above
  • Difficulty: Intermediate
  • Estimated Completion Time: 30 minutes to 1 hour
This entry is part 1 of 2 in the series A Guide to WordPress Custom Post Type

WordPress is built for customization. It was created in such a way that each and every section is customizable. In this tutorial we will be exploring one of the most powerful features of WordPress known as Custom Post Types and how WordPress reached a new height with the advent of this wonderful feature.


What Actually Are Custom Post Types?

Suppose you want your blog to have a separate section for Movie Reviews. By using Custom Post Types you can create a new type of item like Posts and Pages, which will contain a different set of data. It will have a new administration menu, dedicated editing pages, custom taxonomies and many more utilities required for full fledged publishing.

Custom Post Types are a new set of administrative options appearing along with the default post types such as Posts, Pages, Attachments etc. A Custom Post Type can store any type of information. It has a dedicated editor, media uploader and uses the existing WordPress table structure for ease in data management. The main advantage of creating custom post types using the WordPress API is that it equips itself well with existing themes and templates. Custom Post Types are also SEO friendly because of their nifty permalinks.


Why Use Custom Post Types?

Custom Post Types help us to keep different types of posts in different buckets. It separates our regular posts from others. Simple enough!


Let’s Create a Custom Post Type Plugin

Here we shall create a custom post type plugin which will display favorite movie reviews. Lets get started.

Step 1: Create WordPress Plugin Directory

Open your WordPress Plugin directory and create a new directory called Movie-Reviews.

Step 2: Create PHP File

Open the directory and create a PHP file named Movie-Reviews.php.

Step 3: Add Header

Open the file and add the appropriate header at the top.

<?php
/*
Plugin Name: Movie Reviews
Plugin URI: http://wp.tutsplus.com/
Description: Declares a plugin that will create a custom post type displaying movie reviews.
Version: 1.0
Author: Soumitra Chakraborty
Author URI: http://wp.tutsplus.com/
License: GPLv2
*/
?>

Step 4: Register Custom Function

Before the closing of the PHP command, type the following line of code to execute the custom function named create_movie_review during the initialization phase every time a page is generated.

add_action( 'init', 'create_movie_review' );

Step 5: Function Implementation

Provide an implementation of the create_movie_review function.

function create_movie_review() {
	register_post_type( 'movie_reviews',
		array(
			'labels' => array(
				'name' => 'Movie Reviews',
				'singular_name' => 'Movie Review',
				'add_new' => 'Add New',
				'add_new_item' => 'Add New Movie Review',
				'edit' => 'Edit',
				'edit_item' => 'Edit Movie Review',
				'new_item' => 'New Movie Review',
				'view' => 'View',
				'view_item' => 'View Movie Review',
				'search_items' => 'Search Movie Reviews',
				'not_found' => 'No Movie Reviews found',
				'not_found_in_trash' => 'No Movie Reviews found in Trash',
				'parent' => 'Parent Movie Review'
			),

			'public' => true,
			'menu_position' => 15,
			'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'custom-fields' ),
			'taxonomies' => array( '' ),
			'menu_icon' => plugins_url( 'images/image.png', __FILE__ ),
			'has_archive' => true
		)
	);
}

The register_post_type function does most of the work for us. As soon as it is called it prepares the WordPress environment for a new custom post type including the different sections in the admin. This function takes two arguments: the first one is an unique name of the custom post type and the second one an array demonstrating the properties of the new custom post type. Here it’s another array containing the different labels, which indicates the text strings to be displayed in the different sections of the custom post type e.g. ‘name‘ displays the custom post type name in the dashboard, ‘edit‘ and ‘view‘ are displayed in Edit and View buttons respectively. I think the rest are pretty self explanatory.

In the next arguments:

  • 'public' => true determines the visibility of the custom post type both in the admin panel and front end.
  • 'menu_position' => 15 determines the menu position of the custom post type.
  • 'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'custom-fields' ) determines the features of the custom post type which is to be displayed.
  • 'taxonomies' => array( '' ) creates custom taxonomies. Here it’s not defined.
  • 'menu_icon' => plugins_url( 'images/image.png', __FILE__ ) displays the admin menu icon.
  • 'has_archive' => true enables archiving of the custom post type.

Please visit the WordPress Codex register_post_type page for more details on the different arguments used in custom post types.

Step 6: Icon for Custom Post Type

Save a 16×16 pixel icon image in your current plugin folder. This is required for the custom post type icon in the dashboard.

Step 7: Activate the Plugin

Activate the plugin and that’s it, you have a new custom post type which has a text editor, publishing and featured image controls, comment control and the custom fields editor.

Step 8: Add a New Item

Click on the Add New option to go to the custom post type editor. Provide a movie title, a review and set a featured image.

Step 9: Publish

Publish the post and click on View Movie Review to view the created movie review in the browser.


Creating Meta Box Fields for Custom Post Types

The meta box mechanism uses the help of the built in WordPress meta box system and helps to add fields required specifically for the custom post types, without requiring the default custom fields in the editor.

Step 1: Registering the Custom Function

Open the Movie-Reviews.php file and add the following code before the PHP end tag. This registers a function to be called when the WordPress admin interface is visited.

add_action( 'admin_init', 'my_admin' );

Step 2: Implementation of the Custom Function

Add an implementation of the my_admin function which registers a meta box and associates it with the movie_reviews custom post type.

function my_admin() {
	add_meta_box( 'movie_review_meta_box',
		'Movie Review Details',
		'display_movie_review_meta_box',
		'movie_reviews', 'normal', 'high'
	);
}

Here add_meta_box is the function used to add meta boxes to custom post types. Explanation of the given attributes:

  • movie_review_meta_box is the required HTML id attribute
  • Movie Review Details is the text visible in the heading of the meta box section
  • display_movie_review_meta_box is the callback which renders the contents of the meta box
  • movie_reviews is the name of the custom post type where the meta box will be displayed
  • normal defines the part of the page where the edit screen section should be shown
  • high defines the priority within the context where the boxes should show

Step 3: Implementation of the display_movie_review_meta_box Function

<?php
function display_movie_review_meta_box( $movie_review ) {
	// Retrieve current name of the Director and Movie Rating based on review ID
	$movie_director = esc_html( get_post_meta( $movie_review->ID, 'movie_director', true ) );
	$movie_rating = intval( get_post_meta( $movie_review->ID, 'movie_rating', true ) );
	?>
	<table>
		<tr>
			<td style="width: 100%">Movie Director</td>
			<td><input type="text" size="80" name="movie_review_director_name" value="<?php echo $movie_director; ?>" /></td>
		</tr>
		<tr>
			<td style="width: 150px">Movie Rating</td>
			<td>
				<select style="width: 100px" name="movie_review_rating">
				<?php
				// Generate all items of drop-down list
				for ( $rating = 5; $rating >= 1; $rating -- ) {
				?>
					<option value="<?php echo $rating; ?>" <?php echo selected( $rating, $movie_rating ); ?>>
					<?php echo $rating; ?> stars <?php } ?>
				</select>
			</td>
		</tr>
	</table>
	<?php
}
?>

This code renders the contents of the meta box. Here we have used an object variable that contains the information of each of the movie reviews displayed in the editor. Using this object we have retrieved the post ID and used that to query the database to get the associated Director’s name and Rating which in turn render the fields on the screen. When a new entry is added then the get_post_meta returns an empty string which results in displaying empty fields in the meta box.

Step 4: Registering a Save Post Function

add_action( 'save_post', 'add_movie_review_fields', 10, 2 );

This function is called when posts get saved in the database.

Step 5: Implementation of the add_movie_review_fields Function

function add_movie_review_fields( $movie_review_id, $movie_review ) {
	// Check post type for movie reviews
	if ( $movie_review->post_type == 'movie_reviews' ) {
		// Store data in post meta table if present in post data
		if ( isset( $_POST['movie_review_director_name'] ) && $_POST['movie_review_director_name'] != '' ) {
			update_post_meta( $movie_review_id, 'movie_director', $_POST['movie_review_director_name'] );
		}
		if ( isset( $_POST['movie_review_rating'] ) && $_POST['movie_review_rating'] != '' ) {
			update_post_meta( $movie_review_id, 'movie_rating', $_POST['movie_review_rating'] );
		}
	}
}

This function is executed when posts are saved or deleted from the admin panel. Here after checking for the type of received post data, if it is a Custom Post Type then it checks again to see if the meta box elements have been assigned values and then finally stores the values in those fields.

Step 6: Disabling the Default Custom Fields Option

While creating the custom post type we have defined a function create_movie_review. Remove the custom-fields element from the supports array because this is no longer required. Now if you save the file and open the Movie Reviews editor, you will notice two fields in the meta box named Movie Author and Movie Rating. Similarly you can add other elements too.


Creating a Custom Template Dedicated to Custom Post Types

The proper way to display custom post type data is by using custom templates for each of the custom post types. Here we shall create a template which displays all the Movie Reviews entered using the Movie Review Custom Post Type.

Step 1: Register a Function to Force the Dedicated Template

Open the Movie-Reviews.php file and add the following code before the PHP end tag. This registers a function to be called when the WordPress admin interface is visited.

add_filter( 'template_include', 'include_template_function', 1 );

Step 2: Implementation of the function

function include_template_function( $template_path ) {
	if ( get_post_type() == 'movie_reviews' ) {
		if ( is_single() ) {
			// checks if the file exists in the theme first,
			// otherwise serve the file from the plugin
			if ( $theme_file = locate_template( array ( 'single-movie_reviews.php' ) ) ) {
				$template_path = $theme_file;
			} else {
				$template_path = plugin_dir_path( __FILE__ ) . '/single-movie_reviews.php';
			}
		}
	}
	return $template_path;
}

Here the code searches for a template like single-(post-type-name).php in the current theme directory. If it is not found then it looks into the plugin directory for the template, which we supply as a part of the plugin. The template_include hook was used to change the default behavior and enforce a specific template.

Step 3: Create the Single Page Template File

After saving the previously opened plugin file, create another PHP file named single-movie_reviews.php and put the following code in it.

<?php
 /*Template Name: New Template
 */

get_header(); ?>
<div id="primary">
	<div id="content" role="main">
	<?php
	$mypost = array( 'post_type' => 'movie_reviews', );
	$loop = new WP_Query( $mypost );
	?>
	<?php while ( $loop->have_posts() ) : $loop->the_post();?>
		<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
			<header class="entry-header">

				<!-- Display featured image in right-aligned floating div -->
				<div style="float: right; margin: 10px">
					<?php the_post_thumbnail( array( 100, 100 ) ); ?>
				</div>

				<!-- Display Title and Author Name -->
				<strong>Title: </strong><?php the_title(); ?><br />
				<strong>Director: </strong>
				<?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?>
				<br />

				<!-- Display yellow stars based on rating -->
				<strong>Rating: </strong>
				<?php
				$nb_stars = intval( get_post_meta( get_the_ID(), 'movie_rating', true ) );
				for ( $star_counter = 1; $star_counter <= 5; $star_counter++ ) {
					if ( $star_counter <= $nb_stars ) {
						echo '<img src="' . plugins_url( 'Movie-Reviews/images/icon.png' ) . '" />';
					} else {
						echo '<img src="' . plugins_url( 'Movie-Reviews/images/grey.png' ). '" />';
					}
				}
				?>
			</header>

			<!-- Display movie review contents -->
			<div class="entry-content"><?php the_content(); ?></div>
		</article>

	<?php endwhile; ?>
	</div>
</div>
<?php wp_reset_query(); ?>
<?php get_footer(); ?>

Here we have created a basic page template using the loop. The query_posts function retrieves the custom post type elements and displays them using the loop. Of course it is just a basic loop and you can play with it as you want. You can also use proper CSS styles to format the elements accordingly.

Note: You need to create a new page from the dashboard using the newly created template.

Step 4: Images

You need to save two images of star icons 32×32 pixels in your plugin folder. Name them icon.png and grey.png respectively. That’s all, now the movie reviews are displayed on a single page sorted by date.

In my next tutorial I shall cover more features of the Custom Post Types like creating an archived page, creating custom taxonomies, custom columns etc. Please feel free to provide your valuable suggestions.


Other parts in this series:A Guide to WordPress Custom Post Types: Taxonomies, Admin Columns, Filters and Archives
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://twitter.com/Ruturaaj Ruturaaj

    Nice tutorial. Very easy to follow and easy to understand. One query though… do we really require “template_include” filter for Custom Template? I think just following the file name convention is sufficient; or am I missing an important detail here? Please explain to help me understand the need of “template_include” filter and the “include_template_function” function.

    • Soumitra
      Author

      Ruturaaj,

      Here my aim was not to create a custom template but to enforce a dedicated template other than the default single.php which will contain all the data of a single custom post type. I could also have used the template_redirect hook here, which could create a custom template directly from the plugin folder.

      There is no need to create a custom template page from the dashboard still you will find the data in a dedicated template rather than the default one. The template_include hook was used to provide a better support to the custom post type. The include_template_function returns the path to the single-movie_review.php file either from the plugin directory or theme directory.

      Please feel free to share any other better approach for this feature.

  • http://twitter.com/pippinsplugins Pippinsplugins

    Please do not use query_posts() for your template file. Using just the normal loop will work fine. If you must do a custom query, then you must use WP_Query: http://codex.wordpress.org/Class_Reference/WP_Query

    • Oskar Zamorowski

      Can you explain it little bit more?? I’m new to this stuff and confused about query things…

      • http://twitter.com/pippinsplugins Pippinsplugins

        Basically query_posts() is a really, really bad function because it has very significant impacts on performance. There’s a great Stack Exchange discussion on it: http://wordpress.stackexchange.com/questions/50761/when-to-use-wp-query-query-posts-and-pre-get-posts

        • jkd

          @twitter-294079511:disqus How do you change query_post in the code query_posts(array(‘post_type’=>’movie_reviews’)) using WP_Query()

          • http://twitter.com/cphilippsen Christian Philippsen

            You can do something like this:
            $movies = new WP_Query( array( ‘post_type’ => ‘movie_reviews’, ‘order’ => ‘DESC’,
            ‘orderby’ => ‘date’ ) );
            have_posts() ) : $movies->the_post(); ?> … etc …

            Check this reference as well: http://codex.wordpress.org/Class_Reference/WP_Query :)

          • jkd

            @twitter-32605979:disqus and @twitter-21612866:disqus : Thank you very much.

          • http://twitter.com/Gizburdt Gijs Jorissen

            $query = new WP_Query( array(‘post_type’=>’movie_reviews’) )

            while( $query->have_posts() ) : $query->the_post()

            endwhile;

      • http://twitter.com/MaorH Maor Chasen

        Here’s a diagram (by the awesome Rarst) that will help you get familiar with the various query functions. Good luck!

        http://wordpress.stackexchange.com/a/1755

  • http://twitter.com/MaorH Maor Chasen

    Having the template load from the plugin directory is a bad idea, since themes usually differ by the way they organize their markup code. It’s way better to simply place the template file within the theme directory.
    Anyways, was nice reading your article.

    • http://wp.tutsplus.com/ Japh

      Hey Maor, the tutorial actually only uses the template in the plugin directory as a fallback if it’s not in the theme directory. Do you still think this is a bad idea?

      • Nicolas Brisebois-Tétreault

        You need a fallback in case there is no template file for that custom post type in the theme. The fallback file is also usefull. I is a good example to explain how to create a new template file using the custom post type custom fields.

  • Pingback: A Guide to WordPress Custom Post Types: Creation, Display and … | Open Knowledge

  • Soumitra
    Author

    Thanks everyone for pointing that out and starting the discussion. Of
    course it is not necessary to alter the main loop else create a
    secondary loop. But since I haven’t used any pagination it worked fine
    for me.

    Can anybody please share some of the practical issues
    faced while using query_posts()? It would be really helpful for the
    readers and aware them of efficient and bad practices.

    By using WP_Query, we can change the code to:

    ‘movie_reviews’, );
    $loop = new WP_Query( $mypost ); ?>

    have_posts() ) : $loop->the_post();?>
    <article id="post-” >


    Title:
    Director:


    Rating:
    <?php
    $nb_stars = intval( get_post_meta( get_the_ID(), 'movie_rating', true ) );
    for ( $star_counter = 1; $star_counter <= 5; $star_counter++ ) {
    if ( $star_counter <= $nb_stars ) {
    echo '’;
    } else {
    echo ”;
    }
    }
    ?>

    • janw_oostendorp

      why didn’t you update the tutorial code?
      This tutorial is clearly aimed at beginners, they often don’t read comments and just copy & paste code.

      • http://wp.tutsplus.com/ Japh

        The tutorial code has been updated now :)

        • AJ Mallory

          Looks like the download files still need to be updated…

          Thanks for putting this together, it’s nice and simple making it easy to comprehend. That is hard to do, so nice work.

          • http://wp.tutsplus.com/ Japh

            Damn, sorry for that oversight. I’ve updated the source files now too. Thanks for the nudge, @google-25e7f5a0df0a8832613098d5e06c055c:disqus

  • guix69

    Hello, in your next tutorial I wouldn’t mind seeing an admin page for your custom post type with filtering available on the taxonomy :)

  • http://www.facebook.com/dj.karrenbeld Derk-Jan Karrenbeld

    Why is [$mypost = array( 'post_type' => 'movie_reviews', );
    loop = new WP_Query( $mypost );] that in there? If you create single-$post_type or archive-$post_type, the_query is actually queryed by post_type.

  • http://twitter.com/Gizburdt Gijs Jorissen

    I actually made a nice helper to make this process easier. Maybe you can have a look here: https://github.com/Gizburdt/Wordpress-Cuztom-Helper

    • Soumitra
      Author

      Thanks Gijs :)

  • Jamee

    Is it necessary to use a nonce in this plugin? I think I read a similar tut and she created a nonce for the custom_post meta-box.

    • Soumitra
      Author

      Jamee,

      You can create your own nonces for verification of meta boxes and extra security.

  • http://twitter.com/diego3g diego fernandes

    You don’t really need to create a page template for your new custom post type, you just need to create a single-posttypename.php like single-movie.php and wordpress will take it to show the movies. You could show us how to put into RSS and search filters, i know that but it’s more important. But good tutorial.

    • Soumitra
      Author

      Thanks Diego. Actually it acts like a two in one template :) Either create a custom template with the CPT template file OR just use the template file ( with proper navigation elements) through your plugin.

  • Randy Federighi

    In step 3 line 9 you forgot the $ before “loop”. Also, just in case someone is not clear, in step 6 the icon is not “required”. That step is “required” only if you want a custom icon.

    • http://wp.tutsplus.com/ Japh

      Thanks for pointing that out, I’ve fixed up the ‘loop’ error now.

  • http://www.printingray.com/vinyl-sticker-printing.html vinyl stickers

    Thank you for providing this freebie !

  • Pingback: Tweet Parade (no.43 Oct 2012) | gonzoblog

  • Gomy

    Thanks for tut.

    If I don’t complete “Director” field every time, how can I display last 5 movies who have this field (Director) completed? I mean posts_per_page to be conditioned to display only movies with “Director” field is completed.

    Thanks.

    • Guest

      Gomy You may use this:-

      ………………………………………………..
      <?php $mypost = array( 'post_type' => 'movie_reviews', 'posts_per_page' => 5,  'meta_key' => 'movie_director',  'meta_query' =>
           array(
                    array(
                           'key' => 'movie_director',
                           'value' => array(''),
                           'compare' => 'NOT IN',
                            )
                     )
                  );
            $loop = new WP_Query( $mypost ); ?>
      ………………………………………………………………………

    • Soumitra
      Author

      Gomy

      You may use this:-

      ————————-


      <?php $mypost = array( 'post_type' => 'movie_reviews', 'posts_per_page' => 5,  'meta_key' => 'movie_director',  'meta_query' =>

           array(

                    array(

                           'key' => 'movie_director',

                           'value' => array(''),

                           'compare' => 'NOT IN',

                            )

                     )

                  );

       

      ———————————————————

    • Gomy

      Thanks a lot. It works!!

      • Soumitra
        Author

        @disqus_qNMJgoDWa3:disqus You are welcome :)

  • Pingback: A Guide to WordPress Custom Post Types: Taxonomies, Admin Columns, Filters and Archives | Wptuts+

  • Pingback: A Guide to WordPress Custom Post Types: Taxonomies, Admin Columns, Filters and Archives | Wordpress Webdesigner

  • Pingback: My Stream | A Guide to WordPress Custom Post Types: Taxonomies, Admin Columns, Filters and Archives | My Stream

  • edsc

    good post

  • Pingback: Wordpress Custom Post Types | Al Binns' Web Stuff

  • Pingback: Aptakz Crib | A Guide to WordPress Custom Post Types: Creation, Display and Meta Boxes | Wptuts+

  • FilipeCarranoPacheco

    Can someone help me? I’m a beginner and tried to follow the tutorial…. Everything went fine, but after I create the post, I put to see the post and it show “Page not found”. I tried it in two different websites and the same thing happened. Any idea of what that may be?

    • Soumitra
      Author

      It may be permalinks issue. Under register_post_type function please use this-

      'rewrite' => array( 'slug' => 'movies', 'with_front' => false ),

      What type of permalinks are you using?

      • FilipeCarranoPacheco

        It worked!! Thank you very much

        • Soumitra
          Author

          @FilipeCarranoPacheco:disqus You are welcome :)

      • Sheonna Harris

        I’m getting the same “Page not found” error; however when I place the line of code under in my php file the website displays “Parse error: syntax error, unexpected T_DOUBLE_ARROW in /home/shesh87/public_html/visualtrellis.com/wp-content/plugins/movie_reviews/Movie-Reviews.php on line 18″. I don’t understand how to fix this.

        • Sheonna Harris

          Okay, I finally go the Parse error to stop showing up, but the “Page not found” error is still there.

          • Karen

            Curiously, I had the same problem, after the added line provided above by Soumitra. However, I merely changed the permalinks type, and back (post name), and magically it worked.

  • Pingback: Руководство по кастомным типам записей WordPress | Wordpresso

  • Matthieu SIBILLE

    Great tutorial thank you :) ! I have a question though, is it possible to specify in the movie-reviews.php a template for a page to display only links to the published post in your plugin? I’de like to put this template page in the plugin directory not in the theme directory. Thank you !

    • Soumitra
      Author

      It is recommended to place templates in the theme directory but still you can put that in your plugin directory and specify the template path accordingly. Regarding the page to display links, you can
      modify the archive template as specified in part 2 of this tutorial.Thoughts please!

      • http://www.facebook.com/boris.zegarac Boris Zegarac

        I did modified and added the code <a href="”> so I can create the path to each post I publish with your addon, Now the problem is that when I click on the link is loads the real link path but shows the list of all results instead of review content I published. Any idea how to fix this?

  • sarankumar

    I read a lot of tutorials about custome post types.but this tutorial is totatly rocking from others…Like it very much…Thanks a lot :)

    • Soumitra
      Author

      Thanks :)

  • Rakesh Rathore

    thanks its working

  • Reggie

    Hi ! Nice Tutorial !

    But still there is something I just don’t understand.

    Is the single_movie-reviews.php not supposed to behave like the single.php ? For me it looks more like an archives.php showing all the posts.

    What template should I make so that I can see the content of the post ? How do i achieve that ?

  • Reggie368

    Hi ! Nice Tutorial !

    But still there is something I just don’t understand.

    Is the single_movie-reviews.php not supposed to behave like the single.php ? For me it looks more like an archives.php showing all the posts.

    What template should I make so that I can see the content of the post ? How do i achieve that ?

    • Soumitra
      Author

      In this tutorial I have tried to display all the entries of a single custom post type in a dedicated template. If you want to make it behave like the post’s single.php then you just need to create a file single-[custom post type name].php in your theme file and use the following code in it.


      <?php

      get_header(); ?>

      <div id="primary">

      <div id="content" role="main">

      <?php while ( have_posts() ) : the_post(); ?>

      <?php get_template_part( 'content', 'page' ); ?>

      <?php comments_template( '', true ); ?>

      <?php endwhile; // end of the loop. ?>

      <?php get_footer(); ?>

  • emj

    Can’t you achieve this without using a plugin by adding your custom post type into your functions file then calling that function in a particular custom page? (I’m a newbie!) I just read this and now I’m not sure which route to take: http://codex.wordpress.org/Post_Types#Custom_Types

    • Soumitra
      Author

      Of course you can do it. Through this tutorial I also wanted to teach how to create a plugin and also creating a plugin keeps it tidy :)

  • Sochivy

    This is the good post and now I want to make user permission about post type how can it work.

    • Soumitra
      Author

      Can you please explain it further? You can check Japh’s Tutorial for reference.

  • http://www.facebook.com/boris.zegarac Boris Zegarac

    Phenomenal tutorial, I did some modifications to build a review plugin for my smartphones website but there is one thing I have no idea how to add. When on single-movie_reviews.php page I limit the results on 20 reviews for example, how do I make pagination to appear at the bottom since this is custom query. I did try few things but none worked. Please if possible let me know ASAP since the plugin I am working is on live site.

    Thanks a lot for help and again, AWESOME tutorial!

  • Phil Howley

    step 6 – (tip) create a folder called ‘images’ and save your icon as image.png inside it.

  • http://twitter.com/wpmayor WP Mayor

    I have found WP Types to be an excellent alternative to coding everything by hand. WP Types is for me the easiest way to build custom post types and meta boxes via drag and drop, check out our review here: http://www.wpmayor.com/step-by-step/the-best-wordpress-custom-post-type-plugins-types-and-views/

  • Daniel Payne

    I appreciate the info, however when I hover over a Custom Post Type entry there are no links for “Edit View Delete” like on a standard Page or Post. Am I missing something? Thanks.

  • http://twitter.com/IvanaMcConnell Ivana McConnell

    Hello – really helpful tutorial! I was just wondering how the page is generated that lists all the posts. I want to style it specifically; does it just take after index.php?

  • Pingback: Utilizing Eleganttheme’s Testimonial Shortcode | Reyborn Webservices

  • Pingback: Non, WordPress ne sert pas qu'à faire des blogs, et je vous le prouve!

  • http://mydoctortells.com/ Dr. Ashok Koparday

    Lot of learning to do. Today had the satisfaction at beginning with developing a plugin. Wow! Thanks Soumitra Chakraborty.

  • http://www.facebook.com/pieter.baecke Pieter Baecke

    Thanks for the great tutorial. The only thing I didn’t get are the arugments you use for the save_post action:

    add_action( ‘save_post’, ‘add_movie_review_fields’, 10, 2 );

    Why do you use 10,2?

  • http://twitter.com/testotestot testotesto

    Hello!

    First of all, thank you for this amazing guide!

    I have a problem with the post_class of the template file.
    i.e: <article id="post-” >

    I need to get the category ID from each post, which should be output by default, but all it outputs is the ID and the name of the post type:

    For example, for your demo (and mine), this is the output:

    I am trying to identify each post by their category in order to filter the post with the plugin Isotope.

    Do you have a hint in order for me to explore a bit?

    Thank you so much!

  • Sjiamnocna

    I was looking for post about CPT and using add_meta_box for quite long time, and here it is! :D Thank you for it

  • Pingback: Bookmarks for May 18th from 21:47 to 22:06 | dekay.org

  • Jakub McJabbo

    Hi, i know this is older article, but i think it shall work same way in current version WP 3.5.1, right? Well, how is it possible that i stopt just on beggining :-). I made everything – Made new folder Movie-Reviews, inside movie-reviews.php and all code necessary. It works half-way. Movie Reviews custom post type sucesfully appear in my admin menu, i can write new post, public them and so. But when I click “View Movie Review” i got only “We are sorry, but you are looking for something what isn’t here”. I’m still on
    Let’s Create a Custom Post Type Plugin chapter. Is it possible that i need to go next in order to view custom post types? Then why there is L”Step 9: Publish Publish the post and click on View Movie Review to view the created movie review in the browser”. This step don’t work for me. I double checked, use default template, but it doesn’t work. Sorry for my bad english :-)

    • Jakub McJabbo

      I found older comments here that solves this problem, but it is strange. I had /%category%/%postname%/ permalink, then i add:

      ‘rewrite’ => array( ‘slug’ => ‘movies’, ‘with_front’ => false ),

      to my Movie-Reviews.php. Doesn’t work. I changed my permalink to default and suddenly it worked. What is strange on it – then i just change permaling back to /%category%/%postname%/ and it still works … :-) don’t understand it, but i’m glad.

      • Manoj Chandrashekar

        It must be something to do with the flush_rewrite_rules (http://codex.wordpress.org/Function_Reference/flush_rewrite_rules). It is necessary to flush rewrite rules after “activating” your custom post types plugin. This will enable wordpress to build the new permalink rules to handle your custom post type.

        When you reset your permalink structure, that is what just happened and hence, you have it working fine.

  • Jakub McJabbo

    This tutorial is really great, thanks for it. But i have some problem – when i make post in Movie reviews custom post type, publish it and then i click on Display post or Preview post i got this error message:

    Warning: include(/data/web/virtuals/22236/virtual/www/subdom/wp-test-2/wp-content/plugins/Movie-Reviews//single-movie_reviews.php) [function.include]: failed to open stream: No such file or directory in/data/web/virtuals/22236/virtual/www/subdom/wp-test-2/wp-includes/template-loader.php on line 47

    Warning: include() [function.include]: Failed opening ‘/data/web/virtuals/22236/virtual/www/subdom/wp-test-2/wp-content/plugins/Movie-Reviews//single-movie_reviews.php’ for inclusion (include_path=’.:/data/web/virtuals/22236/virtual’) in/data/web/virtuals/22236/virtual/www/subdom/wp-test-2/wp-includes/template-loader.php on line 47

    So – i can display movie review page but not the posts itself, just all reviews on one page. What did i wrong?

  • Pingback: 5 resources for custom WordPress theme development you can’t live with out. | Christmas Webmaster