Creating your own Kinds of Content in WordPress; Part 2: Custom Taxonomies and Fields

Previously, I wrote about how to create your own custom post types in WordPress. This week, I will discuss how to create custom taxonomies (categories) for your custom and default post types as well as how to add custom fields.

Creating your own taxonomies

The technique for creating custom taxonomies is very similar to that of creating custom post types. As with custom post types, I recommend defining custom taxonomies in your own custom plugin rather than relying on a third-party plugin for this purpose. You can add your custom taxonomies to the same plugin you created for your custom post types.

As with custom post types, I utilize WP Generator’s Taxonomy Generator in order to quickly define my custom taxonomies using WordPress’ register_taxonomy function. Here are some of the important configuration arguments:

  • ‘hierarchical’ – whether the taxonomy should support nesting (like categories) or, if set to false, be treated like tags.
  • ‘public’ – whether this taxonomy can be viewed either in the frontend or administrative interface. You will most likely want this to be set to true. This will, in turn, set default values of other variables that control visibility of the taxonomy in different settings.
  • ‘show_in_rest’ – whether the taxonomy is available in Gutenberg blocks

For example, the code for your custom taxonomy may look like this:

// Register Custom Taxonomy
function custom_taxonomy() {

	$labels = array(
		'name'                       => _x( 'Taxonomies', 'Taxonomy General Name', 'text_domain' ),
		'singular_name'              => _x( 'Taxonomy', 'Taxonomy Singular Name', 'text_domain' ),
		'menu_name'                  => __( 'Taxonomy', 'text_domain' ),
		'all_items'                  => __( 'All Items', 'text_domain' ),
		'parent_item'                => __( 'Parent Item', 'text_domain' ),
		'parent_item_colon'          => __( 'Parent Item:', 'text_domain' ),
		'new_item_name'              => __( 'New Item Name', 'text_domain' ),
		'add_new_item'               => __( 'Add New Item', 'text_domain' ),
		'edit_item'                  => __( 'Edit Item', 'text_domain' ),
		'update_item'                => __( 'Update Item', 'text_domain' ),
		'view_item'                  => __( 'View Item', 'text_domain' ),
		'separate_items_with_commas' => __( 'Separate items with commas', 'text_domain' ),
		'add_or_remove_items'        => __( 'Add or remove items', 'text_domain' ),
		'choose_from_most_used'      => __( 'Choose from the most used', 'text_domain' ),
		'popular_items'              => __( 'Popular Items', 'text_domain' ),
		'search_items'               => __( 'Search Items', 'text_domain' ),
		'not_found'                  => __( 'Not Found', 'text_domain' ),
		'no_terms'                   => __( 'No items', 'text_domain' ),
		'items_list'                 => __( 'Items list', 'text_domain' ),
		'items_list_navigation'      => __( 'Items list navigation', 'text_domain' ),
	$args = array(
		'labels'                     => $labels,
		'hierarchical'               => false,
		'public'                     => true,
		'show_ui'                    => true,
		'show_admin_column'          => true,
		'show_in_nav_menus'          => true,
		'show_tagcloud'              => true,
		'show_in_rest'               => true,
	register_taxonomy( 'custom_tax', array( 'post' ), $args );

add_action( 'init', 'custom_taxonomy', 0 );

Add this to your custom plugin you created for your custom post type. In order to use this taxonomy with your custom post type, you will need to add it to the taxonomies argument of that custom post type, for example:

                 'taxonomies'            => array( 'category', 'post_tag', 'custom_tax' ),

Adding custom fields to post types

Adding fields to the default and your custom post types can be done either by adding code to your custom plugin or using an existing third-party plugin to create and manage your fields. This is a situation where I believe using a third party plugin, such as Custom Field Suite, outweighs writing your own code. You can check out my earlier article on other useful third-party WordPress plugins.

Using Custom Field Suite

On installing the Custom Field Suite plugin, you will be able to create separate “Field Groups” – collections of fields that can be added to your post types. Field Groups can also be specified to only be shown under specific criteria; including content containing certain taxonomy terms or even limited to a specific post.

When editing a specific Field Group, may of the available custom field types are self explanatory; there are text, true/false, date, color, WYSIWYG editor and many others provided. One key field that we often use is the “Loop” field. This allows you to nest several fields within what effectively becomes a row. This allows for creation of complex custom field entries.

For example, see the above screenshot of a Loop with nested fields that are used to create “Reviews” which are associated with a custom post type we created called “Production.” The Loop field allows us to add multiple sets of fields that make up a single review. With multiple Loop entries, we can generate a collection of reviews for the Production content type.

Including the custom field to be included in our theme requires us to add PHP code to display the field. For example, we can display all of the reviews for our production using the following:

$reviews = CFS()->get( 'reviews' );
foreach ($reviews as $review) {
  echo '<h3><a href="'.$review['link']['url'].'" target="_blank">'.$review['link']['text'].'</a></h3>';
  if ($review['source'] || $review['date']) echo '<p><strong><em>'.$review['source'].'</em> '.date('F j, Y',strtotime($review['date'])).'</strong></p>';
  echo '<p><em>'.$review['quote'].'</em> &nbsp; <a href="'.$review['link']['url'].'" target="_blank"><strong>Read Review</strong></a></p>';

This code would be added to an appropriate theme file within WordPress’ template hierarchy. In the case of a custom post type, we can make a copy of the single.php template and name it according to our custom post type name. In this above example, the file name is production.php. If the custom post type name_has_underscores the filename would be name-has-underscores.php.


Custom post types, taxonomies and fields allows us to extend WordPress to handle content or our own design. With a little bit of programming, we can make it easy for us to enter and display this custom information consistently as well as create new ways to present it to our audiences. Imagine modifying the above “Reviews” code to display each review in a slideshow, or laying these out in as part of a jQuery UI accordion? With custom fields, post types and taxonomies you can begin to imagine greater possibilities within WordPress.