Why are custom taxonomies only appearing on the edit page of one of these types, but not the other?

The question:

So here’s an odd one. I have custom taxonomies that show on the admin menu of both post types they’re associated with, but only one of the post types shows them in its edit menu. (Over on the side of the post edit screen, where it says Categories, Tags, Featured Image.)

Fresh install of WordPress.
I have 2 custom taxonomies, “formats” and “regions”.
I have 2 post types, “events” and “resources”.

Each are set to use the built-in categories and one or both of those custom taxonomies. They’re each generated by the same function.

The taxonomies and posts are associated correctly – both visible in Admin menus and Quick Edit for Events, only one for Resources- and the main column meta boxes for both display properly and store their values. I can manually “tag” each as expected in Quick Edit.

But the custom taxonomies are only available for selection in the post edit GUI of one of them. Events shows both custom taxonomies and the built-in Categories, Resources only the built-in.

Here’s the code that registers the taxonomies:

function rdcfp_register_custom_taxonomy ($name, $singular_name, $hierarchical, $associated_types) {

    $labels = array(
        'name'          => $name, 
        'singular_name' => $singular_name, 
        'add_new_item'  => 'Add New ' . $singular_name, 
        'edit_item'     => 'Edit ' . $singular_name, 
        'view'          => 'View', 
        'view_item'     => 'View' . $singular_name , 
        'search_items'  => 'Search ' . $name, 
        'menu_name'     => $name         
    );  
    $args = array(
        'label'             => $name,
        'labels'            => $labels,
        'show_ui'           => true,
        'public'            => true, 
        'hierarchical'      => $hierarchical,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array( 'slug' => $name ),

    );    

    register_taxonomy($name, $associated_types, $args);

}

function rdcfp_register_region_taxonomy(){
    rdcfp_register_custom_taxonomy ('Regions', 'Region', false, array('events'));
}
function rdcfp_register_format_taxonomy(){
    rdcfp_register_custom_taxonomy ('Formats', 'Format', false, array('events', 'resources'));
}

Here’s the code the registers the post types:

function rdcfp_create_custom_post_type($name, $singular_name, $description, $hierarchical, $taxonomies, $supports, $menu_icon) {


    $labels = array(
        'name'          => $name, 
        'singular_name' => $singular_name, 
        'add_new_item'  => 'Add New ' . $singular_name, 
        'edit_item'     => 'Edit ' . $singular_name, 
        'view'          => 'View', 
        'view_item'     => 'View' . $singular_name , 
        'search_items'  => 'Search ' . $name, 
        'not_found'     => 'No ' . $name . ' found' , 
        'not_found_in_trash' => 'No ' . $name . ' found in trash'        
        ); 

    $args = array(
        'label'                 => $name,
        'labels'                => $labels,
        'public'                => true, 
        'hierarchical'          => $hierarchical,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'show_in_nav_menus'     => true,
        'show_in_admin_bar'     => true,
        'menu_position'         => 5,
        'can_export'            => true,
        'has_archive'           => true,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'capability_type'       => 'post',
        'show_in_rest'          => true, 
        'description'           => $description,
        'supports'              => $supports,
        'taxonomies'            => $taxonomies,
        'menu_icon'             => $menu_icon
        );

    register_post_type ($name, $args);

}

function rdcfp_create_events_post_type (){

    $name = 'Events';
    $singular_name = 'Event';
    $description = 'A custom post type for Sales events.';
    $hierarchical = false;
    $taxonomies = array('formats','regions', 'category');
    $supports   = array('title', 'featured-image', 'thumbnail', 'excerpt');
    $menu_icon = 'dashicons-calendar-alt';

    rdcfp_create_custom_post_type($name, $singular_name, $description, $hierarchical, $taxonomies, $supports, $menu_icon);
    

}

function rdcfp_create_resources_post_type (){

    $name = 'Resources';
    $singular_name = 'Resource';
    $description = 'A custom post type for consideration-stage content.';
    $hierarchical = false;
    $taxonomies = array('formats','category');
    $supports   = array('title', 'editor','featured-image', 'thumbnail', 'excerpt');
    $menu_icon = 'dashicons-visibility';

    rdcfp_create_custom_post_type($name, $singular_name, $description, $hierarchical, $taxonomies, $supports, $menu_icon);
    
}

Both have custom meta boxes but those fields all appear and store values as expected.

And finally the actions, in case I made an error there:

add_action('init', 'rdcfp_create_events_post_type');
add_action('init', 'rdcfp_create_resources_post_type');
add_action('init', 'rdcfp_register_region_taxonomy', 0);
add_action('init', 'rdcfp_register_format_taxonomy', 0);


I can usually spot a type or dropped argument somewhere when something odd like this happens but I’m stumped. Any hints?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

In short, it’s because your Formats taxonomy is not enabled in the REST API.

Events shows both custom taxonomies and the built-in Categories, Resources only the built-in.

That is actually the expected behavior.

  • The Events post type doesn’t have the editor support, i.e. $supports = array('title', 'featured-image', 'thumbnail', 'excerpt'); — no editor in the list.

  • But the Resources post type has the editor support — $supports = array('title', 'editor','featured-image', 'thumbnail', 'excerpt');, which means the editor will be made available on the post editing screen and the default editor is Gutenberg (the block editor).

Now because Gutenberg uses the WordPress REST API, e.g. when adding/removing/updating a taxonomy term, then the taxonomies associated to a post type must have the show_in_rest argument set to true (i.e. enabled in the REST API) in order for the taxonomy selector UI/panel to be available in the Gutenberg sidebar.

So to fix the issue, you would just need to add 'show_in_rest' => true into your taxonomy arguments:

function rdcfp_register_custom_taxonomy ($name, $singular_name, $hierarchical, $associated_types) {

    $labels = ... your code;
    $args = array(
        'label'             => $name,
        'labels'            => $labels,
        'show_ui'           => true,
        'public'            => true,
        'hierarchical'      => $hierarchical,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array( 'slug' => $name ),
        'show_in_rest'      => true, // add this line

    );

    register_taxonomy($name, $associated_types, $args);

}

Or you could also add a $show_in_rest parameter to your rdcfp_register_custom_taxonomy() function, but I’ll let you write the code for that on your own. 🙂


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment