I’ve been working with Custom Post Types and Custom Taxonomies for ages but one thing I can never get right are the rewrites when applying a shared taxonomy to multiple CPTs.

For instance, I have CPTs for ‘Events’ and ‘Courses’. Each has individual taxonomies and also one shared taxonomy.

The individual taxonomies work fine:

  • Events with a specific topic: /events/topic/{term}/
  • Courses of a specific type: /courses/type/{term}/

However, I have a shared taxonomy called ‘Accessibility Criteria’. With the custom taxonomy defined as it is below, I want (and would expect) to be able to filter each CPT by the shared taxonomy at different URLs:

  • Events with specific accessibility criteria: /events/accessibility/{term}/
  • Courses with specific accessibility criteria: /courses/accessibility/{term}/

But whenever I try and use /events/accessibility/{term}/ it gets rewritten as /accessibility/{term}/. Surprisingly (to me), the context is actually retained correctly e.g. if I trigger the taxonomy from the Events archive then only Event CPTs are shown, so the end-user experience still works fine. However, it doesn’t sit comfortably with me as I feel it should work differently (as well as potentially better SEO etc).

I have defined the custom taxonomies before defining the CPTs as I have read that affects the ability of a CPT to use the taxonomy rewrite.

Any help much appreciated.

$labels = array(
  "name" => __('Accessibility Criteria', ''),
  "singular_name" => __('Accessibility Criteria', ''),
  "add_new_item" => __('Add Accessibility Criteria', ''),
  "new_item_name" => __('Add Accessibility Criteria', ''),
  "edit_item" => __('Edit Accessibility Criteria', ''),
  "view_item" => __('View Accessibility Criteria', ''),
  "update_item" => __('Update Accessibility Criteria', ''),
  "parent_item" => __('Parent Criteria', '')
);
$args = array(
  "label" => __('Accessibility Criteria', ''),
  "labels" => $labels,
  "public" => true,
  "hierarchical" => true,
  "label" => "Accessibility Criteria",
  "show_ui" => true,
  "show_in_menu" => true,
  "show_in_nav_menus" => false,
  "capabilities" => array(
    'manage_terms' => 'manage_accessibility_criteria',
    'edit_terms'   => 'edit_accessibility_criteria',
    'delete_terms' => 'delete_accessibility_criteria',
    'assign_terms' => 'assign_accessibility_criteria'
  ),
  "query_var" => 'accessibility_criteria',
  "rewrite" => array('slug' => 'accessibility', 'with_front' => true),
  "show_admin_column" => true,
  "show_in_rest" => false,
  "rest_base" => "",
  "show_in_quick_edit" => true,
);
register_taxonomy("accessibility_criteria", array("event", "course"), $args);

3 Answers
3

I think you need to add a rewrite rule as the “normal” rewrite rules don’t support your wanted permalink structure. For your use case, you can try it like this:

First: remove the “rewrite” argument from your register_taxonomy arguments (not sure if you definitely need to do this, but it works on my site)

Second: Add the rewrite rule like this in your functions.php

add_action( 'init', 'wpse13483_init' );
function wpse292188_init(){   
    add_rewrite_rule('(events|courses)/accessibility/([^/]+)(/page/?([0-9]{1,}))?/?$','index.php?post_type=$matches[1]&taxonomy=accessibility&term=$matches[2]&paged=$matches[3]','top');
}

Don’t forget to save permalinks after uploading!

Happy Coding!

Leave a Reply

Your email address will not be published. Required fields are marked *