Creating Custom Post Types and Taxonomies: Complete Tutorial
WordPress post types and taxonomies are powerful, underutilized features. Most WordPress users know Posts and Pages, but custom post types and taxonomies unlock WordPress's true flexibility.
Whether you're building a portfolio, product catalog, or specialized application, custom post types and taxonomies organize your content precisely as you need.
What Are Custom Post Types?
Post types are categories of content. WordPress has built-in types:
- Posts - Blog articles
- Pages - Standalone content
- Attachments - Media files
- Revisions - Post history
Custom post types add new content categories. Examples:
- Portfolio - Showcase your work
- Testimonials - Client feedback
- Books - If you're an author
- Products - Alternative to WooCommerce
- Events - Calendar and listing
- Real Estate Listings - Properties with details
What Are Taxonomies?
Taxonomies organize and categorize content. WordPress has built-in taxonomies:
- Categories - For posts
- Tags - Keywords for posts
Custom taxonomies extend this. Examples:
- Project Type (Web Design, Branding, Development)
- Book Genre (Fiction, Non-fiction, Self-help)
- Property Type (Residential, Commercial, Industrial)
- Event Location (New York, London, Tokyo)
Step-by-Step: Creating Your First Custom Post Type
Method 1: Using a Plugin (Easiest)
Best plugins:
- Custom Post Type UI - Intuitive interface, no coding
- Pods - Advanced with relationships
- Toolset Types - Professional, full-featured
Process (Custom Post Type UI):
- Install and activate "Custom Post Type UI"
- Go to CPT UI → Add/Edit Post Types
- Enter post type name: "Portfolio"
- Check desired options (has archive, show in menu, etc.)
- Save
- Post type appears in admin sidebar
Advantages: No coding, visual builder, quick setup
Method 2: Coding (Most Control)
Add this to your theme's functions.php or create a custom plugin:
add_action('init', function() {
register_post_type('portfolio', array(
'labels' => array(
'name' => 'Portfolio',
'singular_name' => 'Portfolio Item',
'add_new_item' => 'Add New Portfolio Item',
'edit_item' => 'Edit Portfolio Item',
),
'description' => 'Portfolio items showcase our work',
'public' => true,
'menu_icon' => 'dashicons-format-gallery',
'menu_position' => 5,
'supports' => array('title', 'editor', 'thumbnail', 'custom-fields'),
'has_archive' => true,
'rewrite' => array('slug' => 'portfolio'),
'show_in_rest' => true, // Enable block editor
));
});
Key parameters explained:
- public - Shows in admin and frontend
- supports - Which editor features available (title, editor, thumbnail, etc.)
- has_archive - Enables /portfolio/ archive page
- rewrite - URL slug for posts
- show_in_rest - Enables WordPress block editor support
- menu_icon - Icon in admin sidebar (use dashicons)
After adding code:
- Save functions.php
- WordPress automatically detects new post type
- "Portfolio" appears in admin sidebar
- Start adding portfolio items
Step-by-Step: Creating Custom Taxonomies
Register a Custom Taxonomy
Add to functions.php:
add_action('init', function() {
register_taxonomy('project_type', 'portfolio', array(
'labels' => array(
'name' => 'Project Types',
'singular_name' => 'Project Type',
'add_new_item' => 'Add New Project Type',
'edit_item' => 'Edit Project Type',
),
'hierarchical' => true, // true = categories, false = tags
'public' => true,
'rewrite' => array('slug' => 'project-type'),
'show_in_rest' => true,
));
});
Register taxonomy with existing post type:
register_taxonomy('project_type', 'portfolio', array(
// options
));
Register taxonomy with multiple post types:
register_taxonomy('project_type', array('portfolio', 'post'), array(
// options
));
Taxonomy parameters:
- hierarchical -
true= categories (parent/child),false= tags (flat) - public - Show in frontend and admin
- rewrite - URL slug structure
- show_in_rest - Enable in block editor
- show_in_quick_edit - Show in post quick edit
Using the Taxonomy in Admin
After registering:
- Go to Portfolio edit screen
- New "Project Types" box appears
- Add taxonomy terms just like categories
- Assign to portfolio items
Advanced: Custom Post Type with Multiple Taxonomies
Real-world example: Real Estate Listing
// Register Real Estate Listing post type
add_action('init', function() {
register_post_type('property', array(
'labels' => array(
'name' => 'Properties',
'singular_name' => 'Property',
),
'public' => true,
'supports' => array('title', 'editor', 'thumbnail', 'custom-fields'),
'has_archive' => true,
'rewrite' => array('slug' => 'property'),
'show_in_rest' => true,
));
// Property Type taxonomy (categories)
register_taxonomy('property_type', 'property', array(
'labels' => array('name' => 'Property Types'),
'hierarchical' => true,
'rewrite' => array('slug' => 'property-type'),
'show_in_rest' => true,
));
// Location taxonomy (tags)
register_taxonomy('location', 'property', array(
'labels' => array('name' => 'Locations'),
'hierarchical' => false,
'rewrite' => array('slug' => 'location'),
'show_in_rest' => true,
));
});
Now your property post type has:
- Property Type (Residential, Commercial, Industrial)
- Location (New York, Los Angeles, Chicago, etc.)
Displaying Custom Post Types on Frontend
List All Items
<?php
$args = array(
'post_type' => 'portfolio',
'posts_per_page' => 12,
);
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
?>
<div class="portfolio-item">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail('medium'); ?>
<h3><?php the_title(); ?></h3>
</a>
</div>
<?php
}
wp_reset_postdata();
}
?>
Filter by Taxonomy
<?php
// Get only "Web Design" portfolio items
$args = array(
'post_type' => 'portfolio',
'tax_query' => array(
array(
'taxonomy' => 'project_type',
'field' => 'slug',
'terms' => 'web-design',
),
),
'posts_per_page' => 12,
);
$query = new WP_Query($args);
// Display results as above
?>
Display on Archive Page
Create archive-portfolio.php in your theme:
<?php
get_header();
?>
<div class="archive-header">
<h1><?php post_type_archive_title(); ?></h1>
</div>
<div class="portfolio-grid">
<?php
if (have_posts()) {
while (have_posts()) {
the_post();
?>
<div class="portfolio-card">
<?php the_post_thumbnail('medium'); ?>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<p><?php echo get_the_excerpt(); ?></p>
</div>
<?php
}
}
wp_pagination();
?>
</div>
<?php get_footer(); ?>
Best Practices
1. Use Plugins for Non-Developers
If you're not comfortable coding:
- Use Custom Post Type UI plugin
- Visual builder eliminates coding
- Generates code automatically (can export later)
2. Keep Post Types Organized
Don't create 20 post types for slightly different content. Use taxonomies to organize instead:
- ✅ One "Event" post type, taxonomy for event type
- ❌ Separate "Conference", "Webinar", "Workshop" post types
3. Enable REST API
Set 'show_in_rest' => true for:
- Block editor support
- API access for headless WordPress
- Mobile app integration
4. Set Correct Permissions
'capabilities' => array(
'edit_post' => 'edit_portfolio',
'edit_posts' => 'edit_portfolios',
'delete_post' => 'delete_portfolio',
'delete_posts' => 'delete_portfolios',
'publish_posts' => 'publish_portfolios',
),
'map_meta_cap' => true,
Prevents unauthorized users from editing.
5. Create Templates for Display
Use plugin like Elementor or Beaver Builder to create custom post type templates without coding.
Querying Custom Post Types
Common queries to fetch content:
All portfolio items:
$args = array('post_type' => 'portfolio', 'posts_per_page' => -1);
By multiple taxonomies (AND):
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'project_type',
'terms' => 'web-design',
),
array(
'taxonomy' => 'location',
'terms' => 'new-york',
),
),
By multiple taxonomies (OR):
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'project_type',
'terms' => array('web-design', 'branding'),
),
),
Conclusion
Custom post types and taxonomies transform WordPress from a blogging platform into a flexible content management system. Combined with custom fields (via ACF or Pods), you can build virtually any content structure.
Start simple: create one custom post type, add a taxonomy, display it on your site. As you gain confidence, expand to more complex structures.
The beauty of WordPress: you can build it yourself (code) or use plugins (visual builders). Choose what fits your skill level.
What custom post types and taxonomies are you using? Share your creative implementations in the comments.
