Blog / WordPress/ Introduction to WordPress Custom Post Types

Introduction to WordPress Custom Post Types

WordPress Custom Post Types are a core feature for theme and plugin development, allowing you to create and manage content types different from standard 'posts' and 'pages'. This article explains how to create a custom post type, add taxonomies and custom fields (meta boxes), and display the content on the front end.

Creating a Custom Post Type

To create a new post type, use the register_post_type() function. Typically, you add this code to your theme's functions.php file.

function my_custom_post_type() {
    $labels = array(
        'name'               => _x( 'Products', 'post type general name' ),
        'singular_name'      => _x( 'Product', 'post type singular name' ),
        'menu_name'          => __( 'Products' ),
        'add_new'            => __( 'Add New' ),
        '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' )
    );
    $args = array(
        'labels'        => $labels,
        'description'   => 'Holds product data',
        'public'        => true,
        'menu_position' => 5,
        'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
        'has_archive'   => true,
        'show_in_rest'  => true // Enables Gutenberg/block editor support
    );
    register_post_type( 'product', $args );
}
add_action( 'init', 'my_custom_post_type' );

After adding the code and refreshing the WordPress admin, you should see a new 'Products' menu item, indicating successful registration.

Adding a Taxonomy to a Custom Post Type

Use the register_taxonomy() function to add a category or tag-like taxonomy to your post type. You must specify the associated post type.

function my_product_taxonomy() {
    $labels = array(
        'name'              => _x( 'Product Categories', 'taxonomy general name' ),
        'singular_name'     => _x( 'Product Category', 'taxonomy singular name' ),
        'search_items'      => __( 'Search Categories' ),
        'all_items'         => __( 'All Categories' ),
        'parent_item'       => __( 'Parent Category' ),
        'parent_item_colon' => __( 'Parent Category:' ),
        'edit_item'         => __( 'Edit Category' ),
        'update_item'       => __( 'Update Category' ),
        'add_new_item'      => __( 'Add New Category' ),
        'new_item_name'     => __( 'New Category Name' ),
        'menu_name'         => __( 'Categories' )
    );
    $args = array(
        'labels'            => $labels,
        'hierarchical'      => true, // true for categories, false for tags
        'show_admin_column' => true, // show column in post list
        'show_in_rest'      => true  // needed for block editor
    );
    register_taxonomy( 'product_cat', 'product', $args );
}
add_action( 'init', 'my_product_taxonomy', 0 );

After adding this, the 'Product Categories' meta box will appear on the 'Product' edit screen.

Adding Custom Fields (Meta Boxes)

Custom fields allow you to store additional information for a post type. For example, add a 'Product URL' field.

First, register the meta box using add_meta_box():

add_action( 'add_meta_boxes', 'add_product_url_meta_box' );
function add_product_url_meta_box() {
    add_meta_box(
        'product_url_meta_box',   // Unique ID
        'Product URL',            // Box title
        'render_product_url_box', // Callback function for HTML
        'product',                // Post type
        'side',                   // Context
        'default'                 // Priority
    );
}

Then, define the callback function to create the form field and handle data saving:

// Render the meta box HTML
function render_product_url_box( $post ) {
    wp_nonce_field( 'save_product_url', 'product_url_nonce' );
    $value = get_post_meta( $post->ID, '_product_url', true );
    echo '';
    echo '';
}
// Save the meta box data
add_action( 'save_post', 'save_product_url_meta' );
function save_product_url_meta( $post_id ) {
    // Security checks
    if ( ! isset( $_POST['product_url_nonce'] ) || ! wp_verify_nonce( $_POST['product_url_nonce'], 'save_product_url' ) ) {
        return;
    }
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }
    if ( isset( $_POST['product_url'] ) ) {
        $url = sanitize_text_field( $_POST['product_url'] );
        update_post_meta( $post_id, '_product_url', $url );
    }
}

You can also display this custom field in the admin post list:

// Add column to post list
add_filter( 'manage_product_posts_columns', 'add_product_url_column' );
function add_product_url_column( $columns ) {
    $columns['product_url'] = 'Product URL';
    return $columns;
}
// Populate the column
add_action( 'manage_product_posts_custom_column', 'show_product_url_column', 10, 2 );
function show_product_url_column( $column, $post_id ) {
    if ( $column === 'product_url' ) {
        echo esc_html( get_post_meta( $post_id, '_product_url', true ) );
    }
}

Displaying Data on the Front End

In your theme template files, you can retrieve and display custom field values:

echo 'Product URL: ' . esc_url( get_post_meta( get_the_ID(), '_product_url', true ) );

To query and loop through custom post type content, use WP_Query:

$args = array(
    'post_type'      => 'product',
    'posts_per_page' => 10,
    'tax_query'      => array( // Optional: filter by taxonomy
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => 'featured'
        )
    )
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
    while ( $query->have_posts() ) : $query->the_post();
        the_title( '

', '

' ); the_content(); $url = get_post_meta( get_the_ID(), '_product_url', true ); if ( $url ) { echo '

View Product

'; } endwhile; wp_reset_postdata(); else : echo '

No products found.

'; endif;

Following these steps, you can create a fully functional custom post type and manage its content effectively.

Post a Comment

Your email will not be published. Required fields are marked with *.