Random writings on running, software & product development, business and anything else

WordPress Custom Post Types

WordPress is best known as a blogging engine, but new features in recent releases and the ability of plugins to add functionality have made WordPress a viable CMS (Content Management System) for sites.

WordPress 3.0 added ‘custom post types’ which allows a developer to define new types of content in addition to the 5 inbuilt types. No longer will posts or pages need to be twisted into shape by use of custom fields or lots of PHP coding. Don’t let the name ‘custom post types’ have you believe the new content is just an extension to WordPress posts. The more correct title is ‘custom content types’.

Create a Custom Post Type

So what can a custom type be? This is up to your need or imagination.

Consider a web site about animals. A custom type called animal could be created to hold all the relevant content on each type of animal. So what would such a WordPress definition look like?

// Custom Content types
add_action( 'init', 'create_custom_types' );

function create_custom_types() {
	  'labels' => array(
		'name' => 'Animals',
		'singular_name' => 'Animal',
		'add_new_item' => 'Add new animal',
		'not_found' => 'No animal found'
	  'description' => 'Content of type animal',
	  'public' => true,
	  'supports' => array('title','editor','custom-fields','revisions','author'),
	  'rewrite' => array('slug' => 'animal')

This will create and make available a very simple custom type of animal. There are many more options which will be covered later. The important functions are register_post_type which is used to create the new type, and add_action for the WordPress hook.

But where does the code go? This code can either be in the functions.php file of your WP theme, or as part of a plugin. Using the functions.php file is great for testing and development, however if you plan to create multiple types and have them available regardless of theme, then I recommend the plugin method, once you have you custom types working.
Now if you log in to the backend of your WP site, you can see the first signs of your new type. On the left hand menu under Comments you will now see a menu item for Animals. Click on animals and you will see a bland screen that there are none, but the possibility to add new.

Admin screen dashboard animal custom type
Admin screen empty animal type list

Click on add new, and you will get a page that is really a cut down version of the standard posts page, but with a heading to add an animal.

Admin add base animal custom type

Custom Taxonomies

Lets now create a more useful animal type. To do this we will create custom taxonomies. WordPress already has built in taxonomies that you already use. In the standard post type, there are categories & tags. In the case of our animal type, we will add 2 taxonomies: Native area (country or continent) & classification (eg. mammal, reptile). There are many other taxonomies that are applicable to animals, but 2 keeps it simple for the time being.
Examining the animal classification in more detail. The required function call is register_taxonomy, followed by a series or parameters. The first is the name of the taxonomy (classification), which must be unique, followed by an array of types the taxonomy can be used on, and then an array of optional parameters. Full details of these can be found on the codex. Of interest for classification is hierarchical which is set to true, the default is false. An hierarchical taxonomy is like the built in categories, which can have a parent/child relationship, as opposed to non hierarchical like native-to which is like the built in tags taxonomy.

// Custom Taxonomies
add_action('init', 'create_taxonomy_types');

function create_taxonomy_types() {
  // Animal native to
	  'public' => true,
	  'labels' => array(
		'name' => 'Native to',
		'singular_name' => 'Native to'
	  'helps' => 'Countries animal native to.'
  // Animal classification
	  'public' => true,
	  'labels' => array(
		'name' => 'Classifications',
		'singular_name' => 'Classification'
	  'helps' => 'Classifications',
	  'hierarchical' => true

So add new with the new animal type and related taxonomies and you will have a screen like below, to which I have added some basic details about the Eastern Grey Kangaroo.
Admin add new custom typev

Add details for an animal, save like a standard post or page, and WordPress handles the storing of details in the database.

Display Type Content

To view a single post WordPress will follow the template hierarchy, and check for single.php and if not found index.php in the theme directory. Custom post types also follow this hierarchy, with the addition of single-type-name.php before single.php. To display any of the new taxonomies associated with the animal custom type, a single-animal.php template file needs to be created. A simplified single-animal.php based on single.php from the TwentyTen theme follows.

get_header(); ?>
		<div id="container">
			<div id="content" role="main">

<?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-meta">
						<?php twentyten_posted_on(); ?>
					</div><!-- .entry-meta -->
					<table class="animal-taxonomy">
	  echo get_the_term_list($post->ID, 'native-to', '<tr><td class="tax">Native To</td><td class="terms">', ', ', '</td></tr>');
	  echo get_the_term_list($post->ID, 'classification', '<tr><td class="tax">Classification</td><td class="terms">', ', ', '</td></tr>');
					<div class="entry-content">
						<?php the_content(); ?>
					</div><!-- .entry-content -->
					<div class="entry-utility">
						<?php twentyten_posted_in(); ?>
						<?php edit_post_link( __( 'Edit', 'twentyten' ), '<span class="edit-link">', '</span>' ); ?>
					</div><!-- .entry-utility -->
				</div><!-- #post-## -->

				<?php comments_template( '', true ); ?>

<?php endwhile; // end of the loop. ?>

			</div><!-- #content -->
		</div><!-- #container -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Display animal custom type single page

get_the_term_list is important here to display relevant taxonomies and associated terms. You will notice that terms such as Australia and Kangaroo are links. Click on them you will be taken to an archive page for that term. In the absence of taxonomy related theme files, archive.php will be used or if not found index.php. To create specific archive pages the theme files to be created from most specific to least are:

  • taxonomy-{taxonomy}-{term}.php
  • taxonomy-{taxonomy}.php
  • taxonomy.php

From Here

This is the basics of custom content and taxonomies in WordPress. Play with the examples are create new custom types. Play with some of the extra options outlined on the WP codex.


  1. Pem McNerney

    Thanks for this post. I’m looking forward to trying out some custom post types at some point and I appreciate the clear explanation.

    • Ernie Leseberg

      Glad it was easy to understand Pem. Future posts to come on custom types that will go into more detail.

  2. ariusz

    Ernie – how would you call your template taxonomy file?

    taxonomy-animal.php ?

    • Ernie Leseberg

      Hi ariusz,
      No the taxonomy template file would be taxonomy-native-to.php

© 2024 Ernie Leseberg

Theme by Anders NorenUp ↑