Custom Post Types for WordPress

By Mike Schinkel
Atlanta WordPress User Group
Sunday October 24, 2010

Overview

Posts

Posts are records in the wp_posts table.

Posts Types

Post Types determine the usage of the Post record.

"Standard" Post Types are "Post" (for blog posts or similar content) and "Page" (for 'static' pages.)

The "post_type" field stores the type:

Post Meta

Post Meta is for extra information about a post (like a Company's Phone number) and it contains Name/Value Pairs of information, one Name/Value Pair for each record. Post Meta records are in the wp_postmeta table.

Taxonomies

The Taxonomy System enabled Categories and Tags as well as custom Taxonomy Terms.

Taxonomy Tables

There are three (3) tables for the Taxonomy system (Taxonony is for post classification).

Plugins (in no particular order):
Reference/Blog Posts/Articles:

Screenshots

For the Theme's functions.php file


<?php
add_action('init','wi_init');
function wi_init() {
  register_post_type('wi_company',array(
    'labels'    => make_post_type_labels('Company','Companies'),
    'public'    => true,
    'show_ui'   => true,
    'rewrite'   => array('slug' => 'companies'),
    'query_var' => 'wi_company',
    'supports'  => array(
      'title',
      'editor',
      'custom-fields'
    ),
  ));
  register_taxonomy('wi_service_area', 'wi_company', array(
    'hierarchical'  => false, // Like Tags
    'labels'        => make_post_type_labels('Service Area'),
    'query_var'     => 'wi_service_area',
    'rewrite'       => array('slug' => 'areas' ),
    )
  );
  register_taxonomy('wi_biz_type', 'wi_company', array(
    'hierarchical'  => true, // Like Categories
    'labels'        => make_post_type_labels('Business Type'),
    'query_var'     => 'wi_biz_type',
    'rewrite'       => array('slug' => 'biztypes' ),
    )
  );
  flush_rewrite_rules(false);
}

function make_post_type_labels($singular,$plural=false,$args=array()) {
  if ($plural===false)
    $plural = $singular . 's';
  elseif ($plural===true)
    $plural = $singular;
  $defaults = array(
    'name'               =>_x($plural,'post type general name'),
    'singular_name'      =>_x($singular,'post type singular name'),
    'add_new'            =>_x('Add New',$singular),
    'add_new_item'       =>__("Add New $singular"),
    'edit_item'          =>__("Edit $singular"),
    'new_item'           =>__("New $singular"),
    'view_item'          =>__("View $singular"),
    'search_items'       =>__("Search $plural"),
    'not_found'          =>__("No $plural Found"),
    'not_found_in_trash' =>__("No $plural Found in Trash"),
    'parent_item_colon'  =>'',
  );
  return wp_parse_args($args,$defaults);
}

/*
  Custom Template Tags
  Consider putting these in your theme's function.php file or in a plugin.
*/
function the_wi_company_address($company=false) {
  if (!$company)
    $company = $GLOBALS['post'];
  $address = get_post_meta($company->ID,'Address',true);
  echo str_replace("\n",'<br/>',$address);
}
function the_wi_company_phone($company=false) {
  if (!$company)
    $company = $GLOBALS['post'];
  echo get_post_meta($company->ID,'Phone',true);
}
function the_wi_company_website($company=false) {
  if (!$company)
    $company = $GLOBALS['post'];
  echo get_post_meta($company->ID,'Website',true);
}
function the_wi_company_service_areas($company=false) {
  if (!$company)
    $company = $GLOBALS['post'];
  echo get_the_term_list( $company->ID, 'wi_service_area',null,', ');
}
function the_wi_company_business_types($company=false) {
  if (!$company)
    $company = $GLOBALS['post'];
  echo get_the_term_list( $company->ID, 'wi_biz_type',null,', ');
}


Theme Template File: single-wi_company.php


<?php
/**
 *
 * single-wi_company.php
 *
 * The Template for displaying all Companies.
 *
 * By Mike Schinkel - http://wordpress.stackexchange.com/users/89/mikeschinkel
 *
 */
get_header(); ?>
<?php
// This styling is here only because I want to make it a self-contained example.
// Consider put this styling in your theme's style.css
?>
<style type="text/css">
#content {
  width:95%;
}
#entry-overview {
  width:60%;
  float:left;
  margin-bottom:20px;
}
#entry-details {
  border-left:1px solid gray;
  padding-left:20px;
  font-size:0.9em;
  width:37%;
  float:right;
  margin-bottom:20px;
}
</style>
<div id="container">
  <div id="content">
  <?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
      <h1 class="entry-title"><?php the_title(); ?></h1>
      <div class="entry-content">
        <div id="entry-overview">
          <h2>Company Overview</h2>
          <p>Business Type(s): <?php the_wi_company_business_types(); ?></p>
          <p>Serving: <?php the_wi_company_service_areas(); ?></p>

        <?php the_content(); ?>

          <?php edit_post_link( __( 'Edit', 'wi' ), '<span class="edit-link">', '</span>' ); ?>
        </div>
        <div id="entry-details">
          <h2>Details</h2>
          <dl>
            <dt>Website:</dt>
              <dd><?php the_wi_company_website(); ?></dd>
            <dt>Phone:</dt>
              <dd><?php the_wi_company_phone(); ?></dd>
            <dt>Address:</dt>
              <dd><?php the_wi_company_address(); ?></dd>
          </dl>
        </div>
      </div>
    </div>
  <?php endwhile; // end of the loop. ?>
  </div><!-- #content -->
</div><!-- #container -->
<?php get_footer(); ?>


Download

You can download a zip file containing the examples here.

In Closing

Hope this helps. If not, ask here.

Need Custom Plugins Developed for your Business? Contact Me