Understanding and creating custom post types

WordPress custom post types
WordPress custom post types

WordPress has by default has few types of content and taxonomies to add our own content. To build website to handle more complicated content we need define custom content types and WordPress has rich tools for creating custom content. Using the following function to create a custom content type in WordPress

<?php register_post_type( $post_type, $args ); ?>

Following is the example of how we can create a Product type in WordPress

add_action( 'init', 'prowp_register_my_post_types' );
function prowp_register_my_post_types() {
  register_post_type( 'products',
   'labels' => array( 'name' => 'Products' ),
   'public' => true,

After you add the above code to your theme’s functions.php you’ll see a admin UI for the content type Products in the Admin Menu. There are many arguments when registering a content type. It is important to know these argumetns

  • public – Sets whether content type is available in Admin UI or in front end of WordPress
  • show_ui – Sets whether content type management is available in Admin Dashboard
  • publicly_queriable – Sets content type can be publicly queriable with argument
  • exclude_from_search – Allows custom content types to be excluded from search results
  • show_in_nav_menus – Whether post type is available for selection in navigation menus
  • supports – This allows what meta boxes to appear while creating or editing a content. It has several options
    • title – Sets the title
    • editor – Displays content editor while editing content with media uploader
    • author – Allows select box to choose author of the post
    • excerpt – Allows excerpt editor while creating content
    • comments – Sets whether comments are enabled for content type
    • trackbacks – Sets whether trackbacks and pingbacks enabled for content type
    • cusotm-fields – Displays custom field editing meta box
    • page-attributes – Displays attributes box for choosing post order.
    • revisions – Displays post revisions meta box
    • post-formats – Displays registered post formats meta box
  • hierarchical – This argument allows you to define if the post type is hierarchical like WordPress pages
  • has_archive – This enables your post type to have an archive page.
  • can_export – Determines whether post type is available for export
  • taxonomies – It takes an array of registered taxonomies to be attached to the post
  • menu_position – Sets position where custom type admin menu shows in dashboard
  • menu_icon – Sets the custom menu icon for the post type
  • show_in_menu – Determines whether to display admin menu for custom post type
  • show_in_admin_bar – Determines whether to display post type in WordPress admin menu bar
  • query_var – This sets query variable for posts of this type
  • rewrite – This sets unique permanent links for this post type. If passed as an array it takes following arguments
    • slug – Sets a a custom permalink slug. Defaults to post_type
    • with_front – Sets whether your post type should use front base from yoru permalink settings
    • pages – Sets whether permalink provides for pagination
    • feeds – Sets whether a feed permalink will be built for this post type

The following example is a common example for creating custom posts with some arguments

add_action( 'init', 'prowp_register_my_post_types' );
function prowp_register_my_post_types() {
$args = array(
 'public' => true,
 'has_archive' => true,
 'labels' => array( 'name' => 'Products' ),
 'taxonomies' => array( 'category' ),
 'rewrite' => array( 'slug' => 'product' ),
 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'comments' )
register_post_type( 'products', $args );
  • labels – Setting labels argument defines what exactly shown in the admin dashboard for custom post types.
    • name – General name for the custom post type. It’s usually plural
    • singular_name – The singular name for the custom post type
    • add_new – The default label for Add new submenu type in admin dasboard
    • add_new_item – The default header text on the main post listing page to add a new post
    • edit_item – Used as a text for editing an individual post
    • new_item – Text for creating new post
    • view_item – Text viewing a single post
    • all_items – Text for all items text in the menu
    • menu_name – Text used in the admin menu
    • name_admin_bar – Text used in the admin bar
    • search_items – Text used for searching posts of this type
    • not_found – Text used for displaying when no posts were found in the search
    • not_found_in_trash – Text shown when no posts are shown in the trash
    • parent_item_colon – Text shown when displaying a post’s parent

Setting these labels help in better administrative experience. The following example shows setting labels while creating custom posts

add_action( 'init', 'prowp_register_my_post_types' );
function prowp_register_my_post_types() {
$labels = array(
'name' => 'Products',
'singular_name' => 'Product',
'add_new' => 'Add New Product',
'add_new_item' => 'Add New Product',
'edit_item' => 'Edit Product',
'new_item' => 'New Product',
'all_items' => 'All Products',
'view_item' => 'View Product',
'search_items' => 'Search Products',
'not_found' => 'No products found',
'not_found_in_trash' => 'No products found in Trash',
'menu_name' => 'Products'
$args = array(
'labels' => $labels,
'public' => true

register_post_type( 'products', $args );

 Working with Custom Post Types

It is the job of themes to display posts in the pages of your WordPress website. However custom post types may not be handled by themes to display on the pages. To display custom post types , use the WP_Query custom loop, it accepts a post_type parameter to determine what kind of posts should be displayed.  It is explained by the following example

$args = array(
'posts_per_page' => '‐1',
'post_type' => 'products',
$myProducts = new WP_Query( $args );
// The Loop
while ( $myProducts->have_posts() ) : $myProducts‐>the_post();
?><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a><br /><?php

 Custom Post Type Template files

archive-{post_type}.php is the archive template file for custom post type

single-{post_type}.php is the template for single entry for your custom post type.  In both the cases post_type is the name of custom post type.

Special Post Type functions

To return a list of all registered post types in WordPress use the following function

<?php get_post_types( $args, $output, $operator ); ?>

To determine post type of a piece of content use the following function. Here $post is post object or post id of the content

<?php get_post_type( $post ); ?>

To verify the custom post type you are looking for exists

<?php post_type_exists( $post_type ); ?>

Here is a useful function to add a support feature for an existing content type

<?php add_post_type_support( $post_type, $supports ) ?>

You an also remove a support feature by using below function

<?php remove_post_type_support( 'products', array( 'thumbnail', 'comments' ) ); ?>

WordPress also features a function to change the post type of a post entry

<?php set_post_type( $post_id, $post_type ); ?>

You can look for the reference function register_post_type() defined in the WordPress codex.

3 Responses

  1. Don’t forget to reset the loop if you are using WP_Query ! If your template is based on the original posts, you could get a rather odd webpage.

Leave a Reply to chirose Cancel reply

Back to Top
%d bloggers like this: