How to Create Custom Post Types

WordPress has five default post types: Post, Page, Attachment, Revision and Navigation Menu. All post types are stored in the wp_posts database table, but are differentiated by a column called post_type.

When these content types are not sufficient for our purposes, we can create our own. Custom post types appear on the left menu, and can be assigned custom templates.


If we don't create any normal posts at all a 404 error will be returned when checking the endpoint. To avoid this problem, add the following filter to your extension and adapt it with your custom post type name:

function your_extension_customfeed_request($request) {
    if ( isset($request['feed']) && !isset($request['post_type']) ) {
        $request['post_type'] = array('post', 'your_custom_post');
    return $request;


A custom post type can be added with the register_post_type() function, like this:

add_action('init', 'create_post_type');
function create_post_type() {
  $labels = array('name' => __('Test Articles'),
      'singular_name' => __('Test Article'));
  $args = array('labels' => $labels,
       'public' => true,
       'menu_position' => 5,
       'has_archive' => true,
       'hierarchical' => true,
       'supports' => array('title', 'editor', 'excerpt', 'thumbnail', 'page-attributes'));
  register_post_type('test_article', $args);
  $taxonomy_name = pugpig_get_taxonomy_name();
  if (!empty($taxonomy_name) && taxonomy_exists($taxonomy_name)) {
   register_taxonomy_for_object_type($taxonomy_name, 'test_article');

The code above creates a post type called Test Article with the identifier test_article. The arguments used in this occasion are:

  • labels: array containing singular and plural labels for the new post type
  • public: indicates whether the type should appear on the administration screens and if it is queryable from the php templates
  • menu_position: position in the menu order the post type should appear
  • has_archive: enables post type archives
  • hierarchical: allows 'Parent' to be specified
  • supports: registers support of the specified features. Possible values:
    • title
    • editor
    • author
    • thumbnail
    • excerpt
    • trackbacks
    • custom-fields
    • comments
    • revisions
    • page-attributes
    • post-formats

A good place to add our custom post types is the extension module for our project (see Your first extension module). In the case of complex post types, however, it makes sense to define them in a separate php file which can also hold any declarations and functions we might need. An example of such a custom post type is Ad Bundles.

Once the post type has been defined (and the extension module activated if that is where it has been defined), it should appear on the left menu:

Featured Images / Thumbnails

A thumbnail image field will be available for all post types if the following line is present in the theme's functions.php:


We can remove that field and display it only for certain post types. If we wanted a thumbnail image only for our custom type, we could remove the previous line from functions.php and add the following in our extension module:

add_theme_support('post-thumbnails', array('test_article'));

Once we have assigned a featured image to a post, we can display it in the template using the following line:



Posts can be displayed using the single.php template file. Our custom post type, respectively, will be displayed using:


where {post_type} is the $post_type argument of the register_post_type() function.

So for the previous example, we should create a file called single-test_article.php. 


Finally, we can use queries in any template to display posts from our custom post type. This is done by passing the post type identifier (i.e. 'test_article') as the post_type argument of WP_Query.

For example:

$args = array( 'post_type' => 'test_article' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
	echo '
'; the_content(); echo '
Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request


Powered by Zendesk