Developer's Roundtable Notes

Session: Creating and Using Custom Post Types

Why CPTs?

An easy way to sort special purpose posts.

An easy way to add custom meta fields and re-arrange the edit screen – without affecting post and page edit screens.

Generally, just a cleaner way to add special posts without complicated queries.
(No need to exclude them from your normal blog page.)

Much simpler for clients to understand and manage.

Easy to create custom layout templates.

Category vs. CPT

When do you need a CPT?

Never need to integrate with posts

A completely different display

Need for custom fields

To make it simpler for client

Some Common Uses for CPTs

FAQs

Testimonials

Staff Bios

Restaurant Menu Items

Events / Calendar Items

Recommended Links

 

 

CPT for FAQs

Create a custom post type for FAQs:

 

CPT for Staff Members

This is the code to create a custom post type for Staff.

 

Adding a Custom Taxonomy

This code creates a custom taxonomy for your CPT.

 

Adding Custom Fields

This code creates a custom meta box for the custom fields.

 

Template Magic

The magic of WordPress templates:

template-hierarchyJust name your template file correctly, and WP does the rest!

Single Page for Staff

Here is the code for displaying a single staff member. Name this page single-lt_staff.php.

 

Archive Page for Staff

Here’s the code for archive-lt_staff.php:

 

Archive Page by Taxonomy

To list staff members by their department, use this code for archive-lt_staff.php instead.

 

Put it into a Plugin

Because your client will be unhappy if they lose all their staff bios when they change to a new theme!

<?
/*
Plugin Name: CPT for Staff Members
Description: Custom Post Type for Staff
Author: Diana Nichols
Version: 1.0
Author URI: http://www.lavenderthreads.com
*/

<?php

/** 1. the custom post type *******************************/

add_action( 'init', 'register_lt_staff' );
function register_lt_staff() {
    $labels = array(
        'name' => 'Staff',
        'singular_name' => 'Staff',
        'add_new' =>  'Add New',
        'add_new_item' => 'Add New Staff',
        'edit_item' => 'Edit Staff',
        'new_item' => 'New Staff',
        'view_item' => 'View Staff',
        'search_items' => 'Search Staff',
        'not_found' => 'No Staff found',
        'not_found_in_trash' => 'No Staff found in Trash',
        'parent_item_colon' => 'Parent Staff:',
        'menu_name' => 'Staff',
    );
    $args = array(
        'labels' => $labels,
        'hierarchical' => false,        
        'supports' => array( 'title', 'editor' , 'page-attributes', 'thumbnail' ),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,  
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'menu_position' => 5,
        'rewrite' =>array( 'slug' => 'staff' ),
        'capability_type' => 'post',
    );
    register_post_type( 'lt-staff', $args );
}

/** 2. the custom taxonomy ******************************/

function register_taxonomy_lt_staff_department() {

    $labels = array(
        'name' => 'Departments',
        'singular_name' => 'Department',
        'search_items' => 'Search Departments',
        'popular_items' => 'Popular Departments',
        'all_items' => 'All Departments',
        'parent_item' => 'Parent Department',
        'parent_item_colon' => 'Parent Department:',
        'edit_item' => 'Edit Department',
        'update_item' => 'Update Department',
        'add_new_item' => 'Add New Department',
        'new_item_name' => 'New Department',
        'separate_items_with_commas' => 'Separate Departments with commas',
        'add_or_remove_items' => 'Add or remove Departments',
        'choose_from_most_used' => 'Choose from the most used Departments',
        'menu_name' => 'Departments',
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'show_in_nav_menus' => true,
        'show_ui' => true,
        'show_tagcloud' => true,
        'show_admin_column' => true,
        'hierarchical' => true,
        'rewrite' => false,

/** 3. the custom fields meta box ************************/

$prefix = 'lt_staff_';

$testimonials_meta_box = array(
    'id' => 'lt_staff-meta-box',
    'title' => 'Staff Info',
    'page' => '_lt_staff',
    'context' => 'side',
    'priority' => 'high',
    'fields' => array(
        array(
        'name' => 'Name',
        'id' => $prefix . 'name',
        'type' => 'text',
        'std' => ''
        ),
        array(
        'name' => 'Title',
        'id' => $prefix . 'title',
        'type' => 'text',
        'std' => ''
        ),
        array(
        'name' => 'Email',
        'id' => $prefix . 'email',
        'type' => 'text',
        'std' => ''
        ),
    )
);

add_action('admin_menu', 'lt_staff_add_box');

/* Add the meta box */
function lt_staff_add_box() {
    global $staff_meta_box;

    add_meta_box($staff_meta_box['id'], $staff_meta_box['title'], 'lt_staff_show_box', $staff_meta_box['page'], $staff_meta_box['context'], $staff_meta_box['priority']);
}

/* DISPLAY the new meta box */
function lt_staff_show_box() {
global $staff_meta_box, $post;

echo '
    <style>
    .ltt_panel label {  
    display: block;  
    font-weight: bold;  
    margin: 6px;  
    margin-bottom: 0;  
    margin-top: 12px;  
    }  
    .ltt_panel input[type="text"] {  
    margin-bottom: 3px;  
    width: 98%;  
    }  
    .ltt_panel h4 {  
    color: #999;  
    font-size: 1em;  
    margin: 15px 6px;  
    text-transform:uppercase;  
    }  
    </style>';

// Use nonce for verification
echo '<input type="hidden" name="lt_staff_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';

echo '<div class="ltt_panel">';
    foreach ($staff_meta_box['fields'] as $field) {    
        // get current post meta data
        $meta = get_post_meta($post->ID, $field['id'], true);       
        echo '<label for="'. $field['id']. '">'. $field['name']. '</label>';
        echo '<input type="text" name="'. $field['id']. '" id="'. $field['id']. '" value="'. $meta. '" />' ;
    }
echo '</div>  ';
}

/* NOW, to save the data */
add_action('save_post', 'lt_staff_save_data');

// Save data from meta box
function lt_staff_save_data($post_id) {
    global $staff_meta_box;

    // verify nonce
    if (!wp_verify_nonce($_POST['lt_staff_meta_box_nonce'], basename(__FILE__))) {
        return $post_id;
    }

    // check autosave
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return $post_id;
    }

    //check QuickEdit
    if (defined('DOING_AJAX') ) {
        return $post_id;
    }

    // check permissions
    if ('page' == $_POST['post_type']) {
    if (!current_user_can('edit_page', $post_id)) {
        return $post_id;
    }
    } elseif (!current_user_can('edit_post', $post_id)) {
        return $post_id;
    }

    foreach ($staff_meta_box['fields'] as $field) {
        $old = get_post_meta($post_id, $field['id'], true);
        $new = $_POST[$field['id']];

        if ($new && $new != $old) {
            update_post_meta($post_id, $field['id'], $new);
        } elseif ('' == $new && $old) {
            delete_post_meta($post_id, $field['id'], $old);
        }
    }
}[/code]

 One caveat here... the custom display pages (single-lt_staff.php and archive-lt_staff.php) need to be included in the theme files.