Beginner's Guide for WordPress - Start your WordPress Blog in minutes.
Choosing the Best
WordPress Hosting
How to Easily
Install WordPress
WordPress Plugins
View all Guides

How to Create Custom Post Types in WordPress

Last updated on by
Special WordPress Hosting offer for WPBeginner Readers
How to Create Custom Post Types in WordPress

Often people mistakenly classify WordPress as just a blogging platform. Over the past years, WordPress has evolved into a robust content management system. By default WordPress comes with post and pages as the main content types. However you can create as many custom content types as you like, and these custom content types are referred to as Custom Post Types. In this article, we will show you how to create custom post types in WordPress. We will also show you how to use them like a pro.

What is Custom Post Type in WordPress?

Custom post types are content types like posts and pages. Since WordPress evolved from a simple blogging platform into a robust CMS, the term post stuck to it. However, a post type can be any kind of content. By default, WordPress comes with these post types:

  • Post
  • Page
  • Attachment
  • Revision
  • Nav Menu

You can create your own custom post types and call them whatever you want. For example if you run a movie review website, then you would probably want to create a movie reviews post type. This post type can have different custom fields and even its own custom category structure. Other examples of post types are: Portfolio, Testimonials, Products, etc.

When doi I need a custom post type?

Check out our article about when do you really need custom post types or taxonomies in WordPress.

Also take a look at WPBeginner’s Deals and Glossary sections. These are custom post types that we created to keep them separate from our regular articles.

You will also notice that we are using custom taxonomies for them instead of categories or tags.

Video Tutorial

If you don’t like the video or need more instructions, then continue reading.

Creating a Custom Post Type – The Easy Way

The easiest way to create a custom post type in WordPress is by using a plugin. This method is recommended for beginner because it is safe and super easy.

First thing you need to do is install and activate the Custom Post Type UI plugin. Upon activation, the plugin will add a new menu item in your WordPress admin menu called CPT UI.

Now go to CPT UI » Add New to create a new custom post type.

Custom Post UI plugin's Add New Page

The Custom Post Type UI plugin also allows you to create custom taxonomies.

This is why the Add new custom post type page is divided into two columns. On your left, you have the form you need to fill to create your custom post type. On your right, you have a form to create a custom taxonomy if you need one.

In the custom post type column, first you need to provide a name for your custom post type. This name cannot exceed more than 20 characters, e.g. movies, recipe, deal, glossary, etc.

Adding your new custom post type

In the next field, you need to provide a label for your custom post type. This label will appear in your WordPress admin bar just like posts and pages. It also needs to be plural to make sense. e.g. Movies, Recipes, Deals, Glossary, etc.

After that you need to provide a singular form for your label. This singular form will be used by WordPress to show instructions and other user interface elements.

Lastly enter a description for your custom post type. This description is simply used to describe what your post type does.

Now you can click on the ‘Create Custom Post Type’ button to add your new custom post type. That’s all.

You can also click on the Advanced Label Options and Advanced Options links to customize more options for your custom post type.

Creating a Custom Post Type Manually

The problem with using a plugin is that your custom post types will disappear when the plugin is deactivated. Any data you have in those custom post types will still be there, but your custom post type will be unregistered and will not be accessible from the admin area.

If you are working on a client site and do not want to install another plugin, then you can manually create your custom post type by adding the required code in your theme’s functions.php file or in a site-specific plugin (See: Custom Post Types Debate functions.php or Plugin).

First we will show you a quick and fully working example so that you understand how it works. Take a look at this code:

// Our custom post type function
function create_posttype() {

	register_post_type( 'movies',
	// CPT Options
			'labels' => array(
				'name' => __( 'Movies' ),
				'singular_name' => __( 'Movie' )
			'public' => true,
			'has_archive' => true,
			'rewrite' => array('slug' => 'movies'),
// Hooking up our function to theme setup
add_action( 'init', 'create_posttype' );

What this code does is that it registers a post type 'movies' with an array of arguments. These arguments are the options of our custom post type. This array has two parts, the first part is labels, which itself is an array. The second part contains other arguments like public visibility, has archive, and slug that will be used in URLs for this post type.

Now lets take a look at a detailed piece of code that adds more options to your custom post type.

* Creating a function to create our CPT

function custom_post_type() {

// Set UI labels for Custom Post Type
	$labels = array(
		'name'                => _x( 'Movies', 'Post Type General Name', 'twentythirteen' ),
		'singular_name'       => _x( 'Movie', 'Post Type Singular Name', 'twentythirteen' ),
		'menu_name'           => __( 'Movies', 'twentythirteen' ),
		'parent_item_colon'   => __( 'Parent Movie', 'twentythirteen' ),
		'all_items'           => __( 'All Movies', 'twentythirteen' ),
		'view_item'           => __( 'View Movie', 'twentythirteen' ),
		'add_new_item'        => __( 'Add New Movie', 'twentythirteen' ),
		'add_new'             => __( 'Add New', 'twentythirteen' ),
		'edit_item'           => __( 'Edit Movie', 'twentythirteen' ),
		'update_item'         => __( 'Update Movie', 'twentythirteen' ),
		'search_items'        => __( 'Search Movie', 'twentythirteen' ),
		'not_found'           => __( 'Not Found', 'twentythirteen' ),
		'not_found_in_trash'  => __( 'Not found in Trash', 'twentythirteen' ),
// Set other options for Custom Post Type
	$args = array(
		'label'               => __( 'movies', 'twentythirteen' ),
		'description'         => __( 'Movie news and reviews', 'twentythirteen' ),
		'labels'              => $labels,
		// Features this CPT supports in Post Editor
		'supports'            => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields', ),
		// You can associate this CPT with a taxonomy or custom taxonomy. 
		'taxonomies'          => array( 'genres' ),
		/* A hierarchical CPT is like Pages and can have
		* Parent and child items. A non-hierarchical CPT
		* is like Posts.
		'hierarchical'        => false,
		'public'              => true,
		'show_ui'             => true,
		'show_in_menu'        => true,
		'show_in_nav_menus'   => true,
		'show_in_admin_bar'   => true,
		'menu_position'       => 5,
		'can_export'          => true,
		'has_archive'         => true,
		'exclude_from_search' => false,
		'publicly_queryable'  => true,
		'capability_type'     => 'page',
	// Registering your Custom Post Type
	register_post_type( 'movies', $args );


/* Hook into the 'init' action so that the function
* Containing our post type registration is not 
* unnecessarily executed. 

add_action( 'init', 'custom_post_type', 0 );

As you can see, we have added many more options to the custom post type with his code. It will add more features like support for revisions, featured image, custom fields, etc.

We have also associated this custom post type with a custom taxonomy called genres. Also notice the part where we have set the hierarchical value to be false. If you would like your custom post type to behave like Pages, then you can set this value to true.

Also notice repeated usage of twentythirteen, this is called text domain. If your theme is translation ready and you want your custom post types to be translated, then you will need to mention text domain used by your theme. You can find your theme’s text domain inside style.css file in your theme directory. Text domain will be mentioned in the header of the file.

Displaying Custom Post Types on Your Site

WordPress comes with built in support for displaying your custom post types. Once you have added a few items into your new custom post type, it is time to display them on your website.

There are a couple of methods that you can use, each one has its own benefits.

Displaying Custom Post Type Using Default Archive Template

First you can simply go to Appearance » Menus and add a custom link to your menu. This custom link is the link to your custom post type. If you are using SEO friendly permalinks then your CPT’s URL will most likely be something like this:

If you are not using SEO friendly permalinks, then your custom post type URL will be something like this:

Replace with your own domain name and movies with your custom post type name. Save your menu and then visit the front-end of your website. You will see the new menu you added, and when you click on it, it will display your custom post type archive page using the archive.php template file in your theme.

Using Custom Templates for CPT Archives and Single Entries

If you don’t like the appearance of the archive page for your custom post type, then you can use dedicated template for custom post type archive. To do that all you need to do is create a new file in your theme directory and name it archive-movies.php. Replace movies with the name of your custom post type.

For geting started, you can copy the contents of your theme’s archive.php file into archive-movies.php template and then start modifying it to meet your needs. Now whenever the archive page for your custom post type is accessed, this template will be used to display it.

Similarly, you can also create a custom template for your post type’s single entry display. To do that you need to create single-movies.php in your theme directory. Don’t forget to replace movies with the name of your custom post type.

You can get started by copying the contents of your theme’s single.php template into single-movies.php template and then start modifying it to meet your needs.

Displaying Custom Post Types on The Front Page

One advantage of using custom post types is that it keeps your custom content types away from your regular posts. However, if you would like them to display among your regular post, then you can do so by adding this code into your theme’s functions.php file or a site-specific plugin:

add_action( 'pre_get_posts', 'add_my_post_types_to_query' );

function add_my_post_types_to_query( $query ) {
	if ( is_home() && $query->is_main_query() )
		$query->set( 'post_type', array( 'post', 'movies' ) );
	return $query;

Don’t forget to replace movies with your custom post type.

Querying Custom Post Types

If you are familiar with the coding and would like to run loop queries in your templates, then here is how to do that (Related: What is a Loop?).

By querying the database, you can retrieve items from a custom post type.

$args = array( 'post_type' => 'movies', 'posts_per_page' => 10 );
$the_query = new WP_Query( $args ); 
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<h2><?php the_title(); ?></h2>
<div class="entry-content">
<?php the_content(); ?> 
<?php wp_reset_postdata(); ?>
<?php else:  ?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

In this code, first we have defined the post type and posts per page in the arguments for our new WP_Query class. After that we ran our query, retrieved the posts and displayed them inside the loop.

Displaying Custom Post Types in Widgets

You will notice that there is a default widget in WordPress to display recent posts. But this widget does not allow you to choose a custom post type. What if you wanted to display latest entries from your newly created post type in a widget? There is an easy way to do this.

First thing you need to do is install and activate the Ultimate Posts Widget plugin. Upon activation, simply go to Appearance » Widgets and drag and drop the Ultimate Posts widget to a sidebar.

This powerful widget will allow you to show recent posts from any post types. You can also display post excerpt with a read more link or even show a featured image next to post title. Configure the widget by selecting the options you want and by selecting your custom post type. After that save your changes and see the widget in action on your website.

More Advance Custom Post Type Tweaks

There is so much more that you can do with your custom post types. You can learn to add your custom post types in main RSS feed or create a separate feed for each custom post type. If you are using Disqus commenting system, then checkout how to disable Disqus for custom post types in WordPress.

We hope this article helped you learn how to create custom post types in WordPress.

If you liked this article, then please subscribe to our YouTube Channel for more WordPress video tutorials. You can also find us on Twitter and Google+.

Editorial Staff at WPBeginner is a team of WordPress experts led by Syed Balkhi. Page maintained by Syed Balkhi.

WPBeginner's Video Icon
Our HD-Quality tutorial videos for WordPress Beginners will teach you how to use WordPress to create and manage your own website in about an hour. Get started now »


  1. Jhon says:

    hey, can you guide me in the process of making a custom glossary like you have on your site?

  2. Anil Reddy says:

    I want to create list type for posts in the category page for my website

  3. david ben oren says:

    how do i clone a post type which has a speicifc table in it, i need to create a seperate post type for other tables.

  4. betty says:

    How do I add a custom field to a Post Type?

  5. Megan says:

    I’ve downloaded the plugin and want to add two custom post types. 1. Fanfiction for all of my writings and 2. Fanart for all of my art.

    For Fanfiction – I want the ability to link chapters together into a story and be able to upload chapters to a story as I write them.

    For Fanart – I’d like to have the focus be on an image (obviously) with a description underneath it

    Is this article what I need or this something completely different?


  6. Zubair Abbas says:


    I simply copied the code to my site’s functions.php. The new post type is visible in the dashboard but when I try to see a post after publishing it, a blank page appears. Later I realised that even the default posts are not opening.

    When I remove the code from functions.php everything works fine again.

    Please help :(


    Zubair Abbas

  7. Alex says:

    I have created the CPT and is working beautifully, but Google cannot find it even after updating sitemaps, using SEO plugins or fetching on Google Webmaster Tools. Any thoughts on why is that happening?

    • WPBeginner Support says:

      It takes Google sometime to start showing new content in search results. Just to be on safe side, check your SEO plugin settings to make sure you are not blocking indexing of your CPTs or CPT archive pages.

  8. Amunet says:

    Creating Custom Post Type can be easy especially with a plugin. The real trick is to show them on the page. Usually you need quite advanced custom development or theme specific plugins like that for Avada.

    Unfortunately there is no universal way to display CPT in WordPress.

    • WPBeginner Support says:

      Actually, there are straight forward and standard ways to display CPTs in WordPress. We have mentioned one in the article above.

  9. Chuck says:

    Great article. How can you modify single post CPT post info based on the custom taxonomy? For instance:

    Date | Author | Series | Book | Topic

    This is easy to write but I want to figure out how to display a modified post info if one the missing taxonomy of Series, like:

    Date | Author | Book | Topic

    Otherwise the default post info displays as:

    Date | Author | | Book | Topic

  10. borahan says:

    I want to diplay specific category posts for current user in page. How can i do it?

  11. Moazam Ali says:


    Thanks for the post. I want to make a library of ebooks and want to use custom post type and portfolio to show the thumbnails of books in front end. Can you please guide how i can do that?

  12. Sharon Wallace says:

    Hello All,
    This is a great plugin. I’m trying to get the taxonomy to show on the page. I created one called Presenters. You can see it here.

    How can I make that happen?

    Thank you

  13. Dave S. says:

    I have created a form (using ArForms plugin) which I need it to be turned into a Post-Type. Do you have any suggestions as to how to accomplish this please?

    Thank you.

  14. Mark Greenway says:

    Thanks for this, exactly what I needed to know to help me get to grips with custom post types.


  15. shashik says:

    Thanks’s very useful..

  16. Graham says:

    Thank you! Just what I was looking for. It’s amazing how many times I find wordpress work-arounds and then forget how I do them and keep having to come back.

    Much appreciated!

  17. Ram says:

    Very useful! Thank you….

  18. MELAS says:


    I don’t have a lot of knowledge about coding. How can I see on the specific page theses Custom post types and taxonomies?

    Thanks in advance!

  19. Mike Ritter says:

    Is there an error? Shouldn’t the function be `create_post_type`?

    • WPBeginner Support says:

      No mike, it is not a core function. You can define this function anyway you want.

  20. Vera says:

    Thank yo for this beautiful tutorial.
    I have gone and done everything as you said.
    Two things I do not understand:
    You have specified taxonomy “genre”. Where is that set up? What if I want to make the actual genres underneath that? How do I make them? Where do I see them?
    I would like to make the menu links to the “Movies” and underneath – sublinks to “Genres”. I can see the “Movies” in the Menu section, each post, like pages. Don’t really need that, but I won’t mind. How to see the “Genres” in there?
    Thank you,

    • WPBeginner Support says:

      Seems like you have successfully created your custom post type, i.e. Movies. The next step is to create custom taxonomy, Genres. A taxonomy is a way to sort content in WordPress. Categories and tags are two default taxonomies that come built in with WordPress and are by default associated with ‘Posts’. Please see our tutorial on how to create custom taxonomies in WordPress. Follow the instructions in that tutorial to create your custom taxonomy Genres and associate it with the post type movies. Your custom taxonomy will appear below the Movies menu in WordPress admin area.

  21. Hamed 3daJoo says:

    I do All Of This but when i want to public a post by this post type my post types redirects to main page (i Just coppied your code without any changes)
    for example i write this post with Movies post type

    please help me ilove post type but i can’t use it correctly

  22. Aaron says:

    Excellent post! Thanks for the content.. helped a lot.

  23. antonio says:

    hi i’m trying to add the snippet of code fort the post type movie… i copied it into functions.php but when i refresh the page nothing is shown. i’m using the twenty fourteen theme… what can be wrong?

  24. ashish shestha says:

    How to display Csutom post type in front End??

  25. Fahd says:

    Hi, Custom post types on my wordpress website were working fine from last 2 years. But what happend is when I change the title of post and click update it save other changes too. But if I keep the post title same and make changes in the post, it doesn’t save it. Any recommendations please?

  26. WPBeginner Staff says:

    Please check out this tutorial on how to show/hide text in WordPress posts with toggle effect.

  27. Arup Ghosh says:

    I want to create a custom post type coupons with reveal coupon option and the code will link to the store url, can you tell me how can I do that. I don’t have much knowledge about coding.

  28. Isaías Subero says:

    Great articule. How can I add icons to custom post types on the wordpress back-end just like it is shown on the picture?

  29. Johan says:

    Hi, the excerpt and the custom fields data is not displaying in the front end… any idea of why this is happening?

  30. Bill Querry says:

    I forgot to mention, prreferably via code for my functions.php file since that’s where the curernet CPT are defined.

  31. Bill Querry says:

    I am looking at a way to add categories to some existing custom post types. Anyone able to point me in the right direction?

  32. Robey Lawrence says:

    I just tried to use the snippet under
    Querying Custom Post Types,
    and figured out it needs a before the reset.

  33. YassinZ says:

    Thanks for the clean handy article
    I just want to use the text editor in the custom post
    so that I can use html tags,

  34. Yassin says:

    thanks for such an awesome clear tutorial
    but I’m faceing a problem in displaying the CPT I’m using SEO friendly permalinks when I direct to may website/movies the CPT are duplicated

  35. Aris Giavris says:

    Very useful! Thank you.

    I would like to add to every tag of my posts one of the following signs: +, -, +/-. May I?

    If so, then I would like to have the choice to represent the signed tags as follow: all the +tags, all the -tags, all the +/-tags.

    I think I am questioning a lot of things.

  36. Placid says:


    I am having a hard time implementing a custom post type correctly. I have searched for a solution for a long time but couldn’t find any. Here’s what I did:

    1. Freshly installed WordPress in my local wamp server (enabled apache rewrite_module first).

    2. Using default theme (twenty fourteen). No plugins installed.

    3. Changed permalinks to “Post name”

    4. In the plugins folder, created a folder named pr_custom_posts and inside that, created a file named pr_custom_posts.php. In the file I created a custom post type. The code is as follows:




    public function register_post_type () {

    $args = array(

    ‘labels’ => array (

    ‘name’ => ‘Movies’,

    ‘singular_name’ => ‘Movie’,

    ‘add_new’ => ‘Add New Movie’,

    ‘add_new_item’ => ‘Add New Movie’,

    ‘edit_item’ => ‘Edit Movie’,

    ‘new_item’ => ‘Add New Movie’,

    ‘view_item’ => ‘View Movie’,

    ‘search_items’ => ‘Search Movies’,

    ‘not_found’ => ‘No Movies Found’,

    ‘not_found_in_trash’ => ‘No Movies Found in Trash’


    ‘query_var’ => ‘movies’,

    ‘rewrite’ => array (

    ‘slug’ => ‘movies/’,

    ‘with_front’=> false


    ‘public’ => true,

    ‘publicly_queryable’ => true,

    ‘has_archive’ => true,

    ‘menu_position’ => 10,

    ‘menu_icon’ => admin_url().’/images/media-button-video.gif’,

    ‘supports’ => array (






    register_post_type(‘jw_movie’, $args);




    add_action(‘init’, function() {

    new PR_Movies_Custom_Post();




    The Good Thing: The CPT is showing in my admin panel and I can add and view movies there.

    THE PROBLEM: I cannot preview the movies in the front end (By clicking the “view” in the CPT in admin panel). It shows in the front end only when I set permalink to default (http://localhost/wp02/?p=123).

    What I have tried:

    1. Go to permalink, keep permalink settings to “Post name” and Save changes.

    2. Use flush_rewrite_rules() in several places (one by one) in my code. Please see the commented out parts in the code above.

    3. Created a menu item as:

    URL: http://localhost/wp02/movies

    Navigation Label: Movies

    This creates a menu item in the front end but shows “Not Found” when “Movies” link is clicked.

    This is driving me crazy. Can anyone please help on this? I would really appreciate.

    • kikilin says:

      I was going crazy too with the same “Not Found” issue, until I tried this: go to Settings > Permalinks and then re-save your settings. I had switched my setting to Default, and then changed it to Post Name (for my project’s needs). After that, links were working as expected.

  37. WPBeginner Staff says:

    Yes sure we will try to make a video tutorial soon. Please subscribe to our YouTube Channel to stay updated.

  38. ceslava says:

    Another easy way is just duplicate the archive.php and rename it to archive-movies.php and the same for single.php -> single-movies.php

    Then you can make tweaks to the php files for your theme.

    Best regards

  39. Mladen Gradev says:

    lol the plugin looks super useful, thanks.

  40. Achilles Khalil says:

    Very hard to display. please can you make a video tutorial ?

  41. Mik says:

    Hi, I’ve been reading and following your posts for so long now, you are amazing, and targeting those missing stuff of beginners… Thank you.

  42. Davide De Maestri says:

    This plugin should be okay, but after every upgrade they’ve got some bug. Due to exporting field, or while migrating from local to remote etc… So It’s better to hand-write the code and put into functions.php :D

Add a Comment

We're glad you have chosen to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and all links are nofollow. Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.