Post Types in WordPress

WordPress Templates

  • There are many different types of content in WordPress. A records content type is described as its Post Type. For example, a regular WP post record has the specific Post Type post, and a page record has the page Post Type. Internally, all of the types of content are stored in the same place — in the wp_posts database table, but are differentiated by a database column called post_type.
  • By default the WordPress Template Hierarchy tries to match the Post Type of the record to a specific theme file to display on the front-end of the website. However, custom logic in template files can override how pages are constructed.
  • The add_post_type_support() function can be used to add support for various WordPress features to specific (default or custom) post-types. For example, by default the Page post type does not support excerpts, but by using add_post_type_support() you can add support.
  • Custom Post Types can be defined using the register_post_type() function from within the functions.php file.
  • Post Types (
  • Post Types (
  • Smashing Magazines Complete Guide To WordPress Custom Post Types

Types of Posts

There are five Post Types available by default in the WordPress:

Post Type slug Description
Post post The post post type is typically used for blogs. A list of posts are normally displayed in a blog in reverse sequential order by time (newest posts first). Posts are also used for creating RSS feeds.
Page page A page is similar to posts however they have some very important differences. Pages aren’t displayed in a reversed time-based order. They can also be placed into a hierarchical order where a page can be the parent or child of another page creating a page structure. Traditionally, pages also do not make use of categories and tags like posts do.
Attachement attachment Attachments are another post type that is special as these hold information about any media that is uploaded to your WordPress website. Not only is the main post information stored where other posts are, attachments also make use of the wp_postmeta table for storing extra information like metadata for images and videos that you’ve added.
Revision revision Revisions are a particularly special post type as they are used to create a history of other post types in case you make a mistake and want to rollback to a previous version. Whilst you technically can’t edit revisions directly unless you restore a revision, they are editable just like posts and are stored in the wp_posts table like any other post type.
Navigation menu nav_menu_item Menus (created by admin users in the admin panel) are lists of links that can be used to navigate your website. This allows admins to create custom lists of links to various locations on the website and are edited in the theme section of the dashboard.

Custom Post Type

Use the WP function register_post_type() with the init action hook in the functions.php theme file to define a custom Post Type.

NOTE: It may be necessary to simply save the Settings > Permalinks page to make the new post type register.

// `Art` custom post type function.
function create_art_posttype() {

    register_post_type( 'art',
        // CPT Options
            'labels' => [
                'name'                => _x('Art', 'taxonomy general name', 'onetheme-text-domain'),
                'singular_name'       => __('Art', 'taxonomy singular name', 'onetheme-text-domain'),
                'menu_name'           => __( 'Art', 'onetheme-text-domain' ),
                'parent_item_colon'   => __( 'Parent Art', 'onetheme-text-domain' ),
                'all_items'           => __( 'All Art', 'onetheme-text-domain' ),
                'view_item'           => __( 'View Art', 'onetheme-text-domain' ),
                'add_new_item'        => __( 'Add New Art', 'onetheme-text-domain' ),
                'add_new'             => __( 'Add New Art', 'onetheme-text-domain' ),
                'edit_item'           => __( 'Edit Art', 'onetheme-text-domain' ),
                'update_item'         => __( 'Update Art', 'onetheme-text-domain' ),
                'search_items'        => __( 'Search Art', 'onetheme-text-domain' ),
                'not_found'           => __( 'Art Not Found', 'onetheme-text-domain' ),
                'not_found_in_trash'  => __( 'Art Not found in Trash', 'onetheme-text-domain' ),
            'public'              => true,
            'has_archive'         => true,
            'rewrite'             => ['slug' => 'art'],
            'show_in_rest'        => true,
            'capability_type'     => 'post',

            // Taxonomies to use. Only the default WP 'category' and 'post_tag' taxonomies need to be chosen here.
            // Each custom taxonomy definition sets which post types they are used with.
            'taxonomies'          => ['category', 'post_tag'],

            // Features this CPT supports in Post Editor
            'supports'            => ['title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields',],

            // A hierarchical CPT is like Pages and can have
            // Parent and child items. A non-hierarchical CPT
            // is like Posts.
            'hierarchical'        => false,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'show_in_nav_menus'   => true,
            'show_in_admin_bar'   => true,
            'menu_position'       => 5,
            'can_export'          => true,
            'exclude_from_search' => false,
            'publicly_queryable'  => true,

// Hooking up our function to theme setup
add_action( 'init', 'create_art_posttype' );

// Add the `art` custom post type thumbnails to the theme.
function add_art_theme_supports() {

    // Add thumbnail support to the `art` type template files.
    add_theme_support('post-thumbnails', ['art']);
add_action('after_setup_theme', 'add_art_theme_supports');

Custom Post Type Template Files

single-{post type ID}.php
archive-{post type ID}.php

Custom Post Type Conditionals

Custom post types will respect the normal is_single() and is_archive() functions but you can also check for specific post types with the is_singular() and get_post_type() functions.

// Single custom post type page.
if( is_singular( 'ww_portfolio' ) )
    do something.

// Check within The Loop.
if( 'ww_portfolio' == get_post_type() )
    do something.

Add a Custom Post Type to the Main Query

// Add custom post-types to the 'Main Query' (Home page).
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',         // Keep the standard 'posts' in the Main Query.
            'ww_portfolio', // Add the custom post-type 'ww_portfolio' to the Main Query.
            //'page',       // Add pages to the Main Query.
        ) );
    return $query;