WordPress Custom Post Types


If you’re familiar with WordPress in anyway, then you are probably familiar with posts. To the average user, posts work like blog entries. They have content and a date associated with them and they are displayed with these two bits of information (as well as a featured image, tags, categories, etc…).

Internally, all the post types are stored in the same place, in the wp_posts database table, but are differentiated by a column called post_type. If you’re familiar with the back end of WordPress then you probably already know that there are 5 default post types built into WordPress. However, if you are less familiar with how WordPress works then the following list of default post types (from the Codex) may surprise you a little:

  • Post (Post Type: ‘post’)
  • Page (Post Type: ‘page’)
  • Attachment (Post Type: ‘attachment’)
  • Revision (Post Type: ‘revision’)
  • Navigation menu (Post Type: ‘nav_menu_item’)

As it turns out, “Page” is actually a post type. Let’s take a look at the difference between a post and a page according to the WordPress Codex page on Post Types:

  • Post in WordPress is a post type that is typical for and most used by blogs. Posts are normally displayed in a blog in reverse sequential order by time (newest posts first). Posts are also used for creating the feeds.
  • Page in WordPress is like post, but it lives outside the normal time-based listings of posts. Pages can use different page templates to display them. Pages can also be organized in a hierarchical structure, with pages being parents to other pages, but they normally cannot be assigned categories and tags. If permalinks are enabled, the permalink of a page is always composed solely of the main site URL and the user-friendly and URL-valid names (also referred to as slug) of the page and its parents if they exist. See the Pages article for more information about the differences.

As you can see (and if you think about it, you would probably realize) pages are really just posts without the time constraint. The main point to take away from this is that post types are really quite customizable, and you can do a lot when creating your own. Almost anything that displays information could be implemented with a custom post type.


For this tutorial, I will be using the example of a “Products” custom post type. The idea is to make our custom post type work very similarly to a product listing application. I will be adding all my code into a plugin – but you are of course welcome to add it into your child theme’s functions.php if you would like. If you are totally unfamiliar with making your own plugin and want to know more, check out my tutorial on how to Create Your Own WordPress Plugin. It has very detailed information on the creation of a plugin if you start to feel lost during this next bit.

The first thing we have to do is create our plugin folder in the wp-content/plugins/ directory. As with everything in programming, you can call it whatever you want. I am calling my folder dobsondev-product-listings. Once you have that created, simply create a PHP file with the same name (eg. mine is called dobsondev-product-listings.php).


The first thing we have to do is register our custom post type. WordPress actually has a built in register_post_type( … ) function for exactly this. It takes in two parameters; first you have the slug name of your post type. This will be used later on when calling your post type so its important for this to be kept track of and for the name to be unique. Secondly you have an array of arguments that tell WordPress what features and settings you want your custom post type to have.

Below is the code to add a new custom post type by hooking our function to the init action. The init action is ran when the plugin is activated (or initialized if that helps you remember).

Let’s go over a few of the nuances of the code above. Firstly, if you want to know more about the arguments that can be supplied to register_post_type( … ) then please check out the Codex page for it. This will give you everything you need to know if you want to do your own thing.

The next thing most people would probably have a question about is the ‘menu_icon’ => ‘dashicons-feedback’ line. Dashicons are the official icon font of the WordPress admin as of 3.8. They can be used very easily to add an icon to your admin side menu item. For a full listing of the icons check out the WordPress Dashicon page. Simply find an icon you like and then copy the second line of the name. All of them start with “dashicons” and then have another combination of words with “-” between. Select on the words with “-” in between and leave out the front “dashicons”.

If you have anything other than the default permalink structure for WordPress, then you are also going to have to manually flush your rewrite rules to ensure your new post type follows the permalink structure of your site. You can flush them by going to “Settings -> Permalinks” in your WordPress back end and clicking the save changes button.

Remember to flush your rewrite rules!

And that’s all there really is to adding your own post type. You can treat this just like any other post when selecting it using the loop, just add ‘post_type’ => ‘dobsondev_products’ to the arguments. Note that this post type will now use the single.php and archive.php templates unless you make new ones in the form of “single-{post_type}.php” and “archive-{post_type}.php”.

This tutorial will also have a second part that will go over adding a custom meta box to our custom post type so that we can display very specific information regarding our post type. I was way behind on getting this tutorial done so that’s why I’m splitting it into two parts like this.

As always thank you for reading and please share it around as much as you can! Please feel free to put any suggestions or ideas for future tutorials in the comments section below.