How to create custom taxonomies in WordPress

Using plugins to create custom taxonomies

Plugins make everything easy and creating a custom taxonomy is no exception. You don’t need any technical knowledge to do it.

The recommended plugins for creating custom taxonomies are Custom Post Types UI and Pods. Let’s try using the former for the example.

  1. Install and activate Custom Post Types UI
  2. Head to CPT UI -> Add/Edit Taxonomies
  3. Complete the box with your taxonomy name. In our case, we use “Floor Exercise”. Also, choose the custom post types on which you want to apply the new taxonomy.
  4. Hit Add Taxonomy button at the bottom.
  5. If you head to Posts -> Add New, the new taxonomy will appear next to the visual editor.You may notice that the new taxonomy is a tag called “Floor Exercise”. What if you want to create a category instead? Easy! Scroll down a bit and change Hierarchical to True.

Adding code to functions.php

Custom Taxonomy in WordPress for custom post type

What is Custom Taxonomy? Custom taxonomy, as the name suggests, allows you to create and define your own taxonomies. It provides a flexible and efficient solution for organizing content beyond the default taxonomies. With custom taxonomy, you can create custom labels, hierarchies, and classifications that are tailored to your website’s unique needs.

Benefits of Custom Taxonomy:

  1. Improved Content Organization: Custom taxonomy empowers you to create a more structured and organized content hierarchy. It helps visitors easily navigate and find relevant content on your website.
  2. Enhanced User Experience: By implementing custom taxonomy, you can create intuitive and user-friendly interfaces, making it easier for visitors to browse through related content and discover relevant information.
  3. Flexible Content Management: Custom taxonomy offers a high degree of flexibility in managing and classifying your content. It allows you to assign multiple taxonomies to a single content item, providing granular control over how content is categorized and displayed.

Implementing Custom Taxonomy in WordPress: To implement custom taxonomy in WordPress, you can utilize a combination of built-in functions and custom code. Here’s a step-by-step guide to get you started:

  1. Define the Taxonomy: Use the register_taxonomy() function to define the taxonomy. Specify the name, labels, and settings for the taxonomy.
  2. Assign Taxonomy to Content: After defining the taxonomy, you can assign it to different content types such as posts, pages, or custom post types. This ensures that the taxonomy becomes available for classification and organization.
  3. Displaying Taxonomy on the Frontend: To showcase the custom taxonomy on your website’s frontend, you need to modify your theme or create custom templates. Utilize functions like get_terms() or get_the_terms() to retrieve and display the taxonomy terms associated with a specific content item.

Practical Use Cases for Custom Taxonomy:

  1. E-commerce Websites: Custom taxonomy can be used to create product categories, attributes, or tags, allowing customers to filter and find products based on specific criteria.
  2. News and Magazine Websites: Implementing custom taxonomy enables you to categorize articles by topics, authors, or regions, enhancing navigation and content discovery.
  3. Events and Listings Websites: Custom taxonomy can help classify events or listings by location, type, or date, making it easier for users to find relevant information.

Conclusion: Custom taxonomy is a powerful tool that expands the capabilities of WordPress, enabling website owners to create personalized and highly organized content structures. By implementing custom taxonomy, you can improve content management, enhance user experience, and make your website more intuitive and user-friendly. Embrace the potential of custom taxonomy and unlock a new level of flexibility and organization within your WordPress site.

 

class Property_CPT_Plugin {
public static function init() {
add_action( ‘init’, [ __CLASS__, ‘register_post_type_and_taxonomies’ ] );
add_action( ‘init’, [ __CLASS__, ‘register_meta_fields’ ] );
add_action( ‘admin_init’, [ __CLASS__, ‘manage_admin_columns’ ] );
// Save meta
add_action( ‘save_post_property’, [ __CLASS__, ‘save_meta’ ], 10, 2 );
// Activation hook (flush rewrite rules)
register_activation_hook( __FILE__, [ __CLASS__, ‘on_activate’ ] );
register_deactivation_hook( __FILE__, [ __CLASS__, ‘on_deactivate’ ] );
}
public static function register_post_type_and_taxonomies() {
$labels = [
‘name’               => ‘Properties’,
‘singular_name’      => ‘Property’,
‘menu_name’          => ‘Properties’,
‘name_admin_bar’     => ‘Property’,
‘add_new’            => ‘Add New’,
‘add_new_item’       => ‘Add New Property’,
‘new_item’           => ‘New Property’,
‘edit_item’          => ‘Edit Property’,
‘view_item’          => ‘View Property’,
‘all_items’          => ‘All Properties’,
‘search_items’       => ‘Search Properties’,
‘not_found’          => ‘No properties found.’,
‘not_found_in_trash’ => ‘No properties found in Trash.’,
];
$args = [
‘labels’             => $labels,
‘public’             => true,
‘show_ui’            => true,
‘show_in_menu’       => true,
‘menu_position’      => 5,
‘menu_icon’          => ‘dashicons-admin-home’,
‘supports’           => [ ‘title’, ‘editor’, ‘thumbnail’, ‘excerpt’, ‘revisions’, ‘custom-fields’ ],
‘has_archive’        => true,
‘rewrite’            => [ ‘slug’ => ‘properties’, ‘with_front’ => false ],
‘show_in_rest’       => true, // enable Gutenberg & REST API
‘capability_type’    => ‘post’,
‘map_meta_cap’       => true,
];
register_post_type( ‘property’, $args );
// Taxonomy: Property Type (e.g., House, Apartment)
register_taxonomy( ‘property_type’, ‘property’, [
‘labels’ => [
‘name’ => ‘Property Types’,
‘singular_name’ => ‘Property Type’,
‘search_items’ => ‘Search Property Types’,
‘all_items’ => ‘All Property Types’,
‘edit_item’ => ‘Edit Property Type’,
‘update_item’ => ‘Update Property Type’,
‘add_new_item’ => ‘Add New Property Type’,
],
‘public’ => true,
‘hierarchical’ => true,
‘show_in_rest’ => true,
‘rewrite’ => [ ‘slug’ => ‘property-type’ ],
] );
// Taxonomy: Features (non-hierarchical)
register_taxonomy( ‘property_feature’, ‘property’, [
‘labels’ => [
‘name’ => ‘Features’,
‘singular_name’ => ‘Feature’,
],
‘public’ => true,
‘hierarchical’ => false,
‘show_in_rest’ => true,
‘rewrite’ => [ ‘slug’ => ‘property-feature’ ],
] );
}
public static function register_meta_fields() {
// Price
register_post_meta( ‘property’, ‘property_price’, [
‘show_in_rest’ => true,
‘type’ => ‘number’,
‘single’ => true,
‘sanitize_callback’ => ‘floatval’,
‘auth_callback’ => function() { return current_user_can( ‘edit_posts’ ); },
] );
// Address
register_post_meta( ‘property’, ‘property_address’, [
‘show_in_rest’ => true,
‘type’ => ‘string’,
‘single’ => true,
‘sanitize_callback’ => ‘sanitize_text_field’,
‘auth_callback’ => function() { return current_user_can( ‘edit_posts’ ); },
] );
// Bedrooms
register_post_meta( ‘property’, ‘property_bedrooms’, [
‘show_in_rest’ => true,
‘type’ => ‘integer’,
‘single’ => true,
‘sanitize_callback’ => ‘intval’,
‘auth_callback’ => function() { return current_user_can( ‘edit_posts’ ); },
] );
}
// Add meta boxes manually for nicer admin UI
public static function manage_admin_columns() {
add_action( ‘add_meta_boxes’, function() {
add_meta_box( ‘property_details_box’, ‘Property Details’, [ __CLASS__, ‘render_meta_box’ ], ‘property’, ‘normal’, ‘high’ );
} );
// Admin columns
add_filter( ‘manage_property_posts_columns’, function( $cols ) {
$cols_before = [
‘cb’ => $cols[‘cb’],
‘title’ => $cols[‘title’],
‘property_price’ => ‘Price’,
‘property_bedrooms’ => ‘Beds’,
‘property_address’ => ‘Address’,
‘date’ => $cols[‘date’],
];
return $cols_before;
} );
add_action( ‘manage_property_posts_custom_column’, function( $column, $post_id ) {
if ( ‘property_price’ === $column ) {
$price = get_post_meta( $post_id, ‘property_price’, true );
if ( $price !== ” ) {
echo esc_html( number_format_i18n( floatval( $price ), 2 ) );
} else {
echo ‘—’;
}
}
if ( ‘property_bedrooms’ === $column ) {
echo esc_html( get_post_meta( $post_id, ‘property_bedrooms’, true ) ?: ‘—’ );
}
if ( ‘property_address’ === $column ) {
echo esc_html( get_post_meta( $post_id, ‘property_address’, true ) ?: ‘—’ );
}
}, 10, 2 );
}
public static function render_meta_box( $post ) {
wp_nonce_field( ‘property_details_nonce’, ‘property_details_nonce_field’ );
$price = get_post_meta( $post->ID, ‘property_price’, true );
$address = get_post_meta( $post->ID, ‘property_address’, true );
$bedrooms = get_post_meta( $post->ID, ‘property_bedrooms’, true );
?>
<p>
<label for=”property_price”>Price</label><br />
<input type=”number” step=”0.01″ name=”property_price” id=”property_price” value=”<?php echo esc_attr( $price ); ?>” style=”width:100%;” />
</p>
<p>
<label for=”property_bedrooms”>Bedrooms</label><br />
<input type=”number” name=”property_bedrooms” id=”property_bedrooms” value=”<?php echo esc_attr( $bedrooms ); ?>” style=”width:100px;” />
</p>
<p>
<label for=”property_address”>Address</label><br />
<input type=”text” name=”property_address” id=”property_address” value=”<?php echo esc_attr( $address ); ?>” style=”width:100%;” />
</p>
<?php
}
public static function save_meta( $post_id, $post ) {
// Check autosave
if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ) {
return;
}
// Verify nonce
if ( empty( $_POST[‘property_details_nonce_field’] ) || ! wp_verify_nonce( wp_unslash( $_POST[‘property_details_nonce_field’] ), ‘property_details_nonce’ ) ) {
return;
}
// Capability
if ( ! current_user_can( ‘edit_post’, $post_id ) ) {
return;
}
// Save fields
if ( isset( $_POST[‘property_price’] ) ) {
update_post_meta( $post_id, ‘property_price’, floatval( wp_unslash( $_POST[‘property_price’] ) ) );
}
if ( isset( $_POST[‘property_bedrooms’] ) ) {
update_post_meta( $post_id, ‘property_bedrooms’, intval( wp_unslash( $_POST[‘property_bedrooms’] ) ) );
}
if ( isset( $_POST[‘property_address’] ) ) {
update_post_meta( $post_id, ‘property_address’, sanitize_text_field( wp_unslash( $_POST[‘property_address’] ) ) );
}
}
public static function on_activate() {
// Ensure CPT & tax registered so rewrite rules flush correctly
self::register_post_type_and_taxonomies();
flush_rewrite_rules();
}
public static function on_deactivate() {
flush_rewrite_rules();
}
}
Property_CPT_Plugin::init();
register a Property Location taxonomy for your existing Property custom post type.
// === Register Taxonomy: Property Location ===
function register_property_location_taxonomy() {
$labels = array(
‘name’              => ‘Property Locations’,
‘singular_name’     => ‘Property Location’,
‘search_items’      => ‘Search Property Locations’,
‘all_items’         => ‘All Locations’,
‘parent_item’       => ‘Parent Location’,
‘parent_item_colon’ => ‘Parent Location:’,
‘edit_item’         => ‘Edit Location’,
‘update_item’       => ‘Update Location’,
‘add_new_item’      => ‘Add New Location’,
‘new_item_name’     => ‘New Location Name’,
‘menu_name’         => ‘Locations’,
);
$args = array(
‘hierarchical’      => true, // true = behaves like categories (nested), false = like tags
‘labels’            => $labels,
‘show_ui’           => true,
‘show_admin_column’ => true,
‘query_var’         => true,
‘show_in_rest’      => true, // enables Gutenberg + REST API
‘rewrite’           => array( ‘slug’ => ‘property-location’ ),
);
register_taxonomy( ‘property_location’, array( ‘property’ ), $args );
}
add_action( ‘init’, ‘register_property_location_taxonomy’ );
Share on Facebook Share on Twitter