The main point of this article is to show you how to create multiple Custom Taxonomies using a more easy and re-usable approach.

We’re going to create a file called custom-taxonomies.php and place it a folder called ‘config’ inside your theme.

In custom-taxonomies.php we’re going to create a class that will generate Custom Taxonomies. It will be called DM_Project_Custom_Taxonomy.

<?php
class DM_Project_Custom_Taxonomy {

} // End class

new DM_Project_Custom_Taxonomy;

In here we create 3 fuctions: a __construct, one to define the custom taxonomies and one that will register them.

<?php
class DM_Project_Custom_Taxonomy {

    public function __construct() {
		
    }

    public function all_custom_taxonomies() {

    }

    private function dm_register_custom_taxonomy( $data ) {

    }

} // End class

new DM_Project_Custom_Taxonomy;

In the all_custom_taxonomies function we define all the custom post types that we want to use and will pass that data into the dm_register_custom_taxonomy.

public function all_custom_taxonomies() {
	$custom_taxonomies = [
		[
			'taxonomy_type' => 'custom_taxonomy',
			'singular' => 'Custom Taxonomy',
			'plural' => 'Custom Taxonomies',
			'slug' => 'custom-taxonomy',
			'custom_post_type' => 'post',
		],
		[
			'taxonomy_type' => 'second_custom_taxonomy',
			'singular' => 'Second Custom Taxonomy',
			'plural' => 'Other Custom Taxonomies',
			'slug' => 'second-custom-taxonomy',
			'custom_post_type' => 'my_custom_taxonomy_type',
		],


	];

	foreach ($custom_taxonomies as $key => $custom_taxonomy) {
		$this -> dm_register_custom_taxonomy( $custom_taxonomy );
	}
}

And the dm_register_custom_taxonomy will look like this

private function dm_register_custom_taxonomy( $data ) {

	$singular  = $data['singular'];
	$plural    = ( isset( $data['plural'] ) ) ? $data['plural'] : $data['singular'] . 's';
	$custom_taxonomy = $data['taxonomy_type'];
	$slug = $data['slug'];
	$custom_post_type = $data['custom_post_type'];

	$labels = array(
		'name'               => _x( $plural, 'post type general name', 'dm-artillerie-theme' ),
		'singular_name'      => _x( $singular, 'post type singular name', 'dm-artillerie-theme' ),
		'menu_name'          => _x( $plural, 'admin menu', 'dm-artillerie-theme' ),
		'name_admin_bar'     => _x( $singular, 'add new on admin bar', 'dm-artillerie-theme' ),
		'add_new'            => _x( 'Add New', $singular, 'dm-artillerie-theme' ),
		'add_new_item'       => __( 'Add New ' . $singular, 'dm-artillerie-theme' ),
		'new_item'           => __( 'New ' . $singular, 'dm-artillerie-theme' ),
		'edit_item'          => __( 'Edit ' . $singular, 'dm-artillerie-theme' ),
		'view_item'          => __( 'View ' . $singular, 'dm-artillerie-theme' ),
		'all_items'          => __( 'All ' . $plural, 'dm-artillerie-theme' ),
		'search_items'       => __( 'Search ' . $plural, 'dm-artillerie-theme' ),
		'parent_item_colon'  => __( 'Parent ' . $plural . ':', 'dm-artillerie-theme' ),
		'not_found'          => __( 'No ' . $plural . ' found.', 'dm-artillerie-theme' ),
		'not_found_in_trash' => __( 'No ' . $plural . ' found in Trash.', 'dm-artillerie-theme' )
	);

	$args = array(
		'labels'             => $labels,
		'description'        => __( $singular .'.', 'dm-artillerie-theme' ),
		'public'             => true,
		'publicly_queryable' => true,
		'show_ui'            => true,
		'show_in_menu'       => true,
		'query_var'          => true,
		'rewrite'            => array( 'slug' => $slug ),
		'capability_type'    => 'post',
		'has_archive'        => false,
		'hierarchical'       => false,
		'menu_position'      => null,
		'supports'           => array( 'title', 'author', 'thumbnail', 'excerpt', 'comments' )
	);

	register_taxonomy( $custom_taxonomy, array($custom_post_type) , $args );

}

If you want to do a small adjustment you can also define a variable from ‘textdomain’. In my case that is ‘dm-artillerie-theme’ and it’s hardcoded in there.

Now in the __construct we make sure to init the all_post_types function

public function __construct() {
	add_action( 'init', array( $this, 'all_custom_taxonomies' ) );
}

Your final code in the custom-taxonomies.php file should look like this:

<?php
class DM_Project_Custom_Taxonomy {

    public function __construct() {
        add_action( 'init', array( $this, 'all_custom_taxonomies' ) );
    }

	public function all_custom_taxonomies() {
		$custom_taxonomies = [
			[
				'taxonomy_type' => 'custom_taxonomy',
				'singular' => 'Custom Taxonomy',
				'plural' => 'Custom Taxonomies',
				'slug' => 'custom-taxonomy',
				'custom_post_type' => 'post',
			],
			[
				'taxonomy_type' => 'second_custom_taxonomy',
				'singular' => 'Second Custom Taxonomy',
				'plural' => 'Other Custom Taxonomies',
				'slug' => 'second-custom-taxonomy',
				'custom_post_type' => 'my_custom_post_type',
			],


		];

		foreach ($custom_taxonomies as $key => $custom_taxonomy) {
			$this -> dm_register_custom_taxonomy( $custom_taxonomy );
		}
	}

    private function dm_register_custom_taxonomy( $data ) {

        $singular  = $data['singular'];
        $plural    = ( isset( $data['plural'] ) ) ? $data['plural'] : $data['singular'] . 's';
        $custom_taxonomy = $data['taxonomy_type'];
        $slug = $data['slug'];
        $custom_post_type = $data['custom_post_type'];

        $labels = array(
            'name'               => _x( $plural, 'post type general name', 'dm-artillerie-theme' ),
            'singular_name'      => _x( $singular, 'post type singular name', 'dm-artillerie-theme' ),
            'menu_name'          => _x( $plural, 'admin menu', 'dm-artillerie-theme' ),
            'name_admin_bar'     => _x( $singular, 'add new on admin bar', 'dm-artillerie-theme' ),
            'add_new'            => _x( 'Add New', $singular, 'dm-artillerie-theme' ),
            'add_new_item'       => __( 'Add New ' . $singular, 'dm-artillerie-theme' ),
            'new_item'           => __( 'New ' . $singular, 'dm-artillerie-theme' ),
            'edit_item'          => __( 'Edit ' . $singular, 'dm-artillerie-theme' ),
            'view_item'          => __( 'View ' . $singular, 'dm-artillerie-theme' ),
            'all_items'          => __( 'All ' . $plural, 'dm-artillerie-theme' ),
            'search_items'       => __( 'Search ' . $plural, 'dm-artillerie-theme' ),
            'parent_item_colon'  => __( 'Parent ' . $plural . ':', 'dm-artillerie-theme' ),
            'not_found'          => __( 'No ' . $plural . ' found.', 'dm-artillerie-theme' ),
            'not_found_in_trash' => __( 'No ' . $plural . ' found in Trash.', 'dm-artillerie-theme' )
        );

        $args = array(
            'labels'             => $labels,
            'description'        => __( $singular .'.', 'dm-artillerie-theme' ),
            'public'             => true,
            'publicly_queryable' => true,
            'show_ui'            => true,
            'show_in_menu'       => true,
            'query_var'          => true,
            'rewrite'            => array( 'slug' => $slug ),
            'capability_type'    => 'post',
            'has_archive'        => false,
            'hierarchical'       => false,
            'menu_position'      => null,
            'supports'           => array( 'title', 'author', 'thumbnail', 'excerpt', 'comments' )
        );

        register_taxonomy( $custom_taxonomy, array($custom_post_type) , $args );

    }


} // End class

new DM_Project_Custom_Taxonomy;

In functions.php add the PHP file that you just worked on:

require_once('config/custom-taxonomies.php');

Using this code you’ll be able to generate multiple custom taxonomies without having to repeat the code and easily assigning the post type.

This is also a very clean way of keeping your code and not putting everything in functions.php. Use separate files and just call them from function.php.

You can find a similar article on how to create multiple Custom Post Types with the same approach.