so I notice when you type the URL of a post with a category (eg category5/post), it will automatically forward to the correct category in the URL (eg category5 changes to category1) if the category doesn't match the post.

I can't seem to be able to do this with taxonomies and custom post types.

Using WP_Debug plugin I tried to see if it was something to do with the request itself.


Query String:

Matched Rewrite Rule:

Matched Rewrite Query:

No problem there. it redirects to this rewrite query no matter what I type for the category. Here is the one for my taxonomies and custom post types.


Query String:

Matched Rewrite Rule:

Matched Rewrite Query:

It's practically identical aside from the fact I had to use a different rewrite rule since the default one didn't work properly (i couldn't view the taxonomy archive pages).. see below. The rest of the site functions perfectly with it!

     $newRules['my/(.+?)/(.+?)/([^/]+)/?$'] = 'index.php?mycategory=$matches[1]%2F$matches[2]&post_type=my&name=$matches[3]';
    $newRules['my/(.+)/?$']           = 'index.php?mycategory=$matches[1]';


Registering my custom post type and taxonomy, I used these values for args.

                       'public' => true,
                       'publicly_queryable' => true,
                       'show_ui' => true,
                       'query_var' => true,
                       'rewrite' => array(
                            'slug' => 'my/%mycategory%',
                            'with_front' => true,
                           'pages' => true
                       'capability_type' => 'post',

                       'hierarchical' => true,

and taxonomy

        'query_var' => true,
        'show_ui' => true,
        'has_archive' => true,
        'show_tagcloud' => false,
        'hierarchical' => true,
        'with_front' => true,

        'rewrite' => array(
            'slug' => 'my',
            'with_front' => true,
            'hierarchical' => true

In addition to the rewrite rules, I utilised this code (I'm not sure how relevant all this code is.)

function filter_post_type_link($link, $post)
    if ($post->post_type != 'my')
        return $link;

    if ($cats = get_the_terms($post->ID, 'mycategory'))
    $link = str_replace('%mycategory%', get_taxonomy_parents(array_pop($cats)->term_id, 'mycategory', false, '/', true), $link);
return $link;
add_filter('post_type_link', 'filter_post_type_link', 10, 2);

function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array()) {
$chain = '';
$parent = &get_term($id, $taxonomy);

if (is_wp_error($parent)) {
    return $parent;

if ($nicename)
    $name = $parent -> slug;
    $name = $parent -> name;

if ($parent -> parent && ($parent -> parent != $parent -> term_id) && !in_array($parent -> parent, $visited)) {
    $visited[] = $parent -> parent;
    $chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $separator, $nicename, $visited);


if ($link) {

} else
    $chain .= $name . $separator;
return $chain;

function restrict_things_by_category() {
global $typenow;
$post_type = 'my';
$taxonomy = 'mycategory';
if ($typenow == $post_type) {
    $selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
    $info_taxonomy = get_taxonomy($taxonomy);
        'show_option_all' => __("Show All {$info_taxonomy->label}"),
        'taxonomy' => $taxonomy,
        'name' => $taxonomy,
        'orderby' => 'name',
        'selected' => $selected,
        'show_count' => true,
        'hide_empty' => true,

add_action('restrict_manage_posts', 'restrict_things_by_category');

function convert_id_to_term_in_query($query) {
global $pagenow;
$post_type = 'my';
$taxonomy = 'mycategory';
$q_vars = &$query->query_vars;
if ($pagenow == 'edit.php' && isset($q_vars['post_type']) && $q_vars['post_type'] == $post_type && isset($q_vars[$taxonomy]) && is_numeric($q_vars[$taxonomy]) && $q_vars[$taxonomy] != 0) {
    $term = get_term_by('id', $q_vars[$taxonomy], $taxonomy);
    $q_vars[$taxonomy] = $term->slug;

add_filter('parse_query', 'convert_id_to_term_in_query');

Please help because this is driving me nuts, and the purpose of the site is for users to submit content... it's uncategorised at first but if they share it and it becomes categorised later it needs to forward to the correct URL... plus I'm thinking this might hurt SEO as well?

This code was originally used so I could have hierarchical URLs generated. eg

parent term (example.com/my/parent/) shows content all related to parent term incl. all child terms child term (example.com/my/parent/child) shows content only within that child term custom post (example.com/my/parent/child/post/) is the post, and any new created post with the child term 'checked' will generate this URL. else it will just generate (example.com/my/%mycategory%/post) which of course results in a 404...

Here's code from previous answer that still doesn't seem to work - it doesn't seem to make any changes for wp_query either, though if I use 'key' for the array() it detects that.. but I don't think that's what I'm after.

 function wpd_single_cpt_queries( $query ){
   if( $query->is_singular()
     && $query->is_main_query()
     && isset( $query->query_vars['mycategory'] ) ){
     $tax_query = array(
             'taxonomy' => 'mycategory',
             'field' => 'slug',
             'terms' => $query->query_vars['mycategory']

     $query->set( 'tax_query', $tax_query );

   add_action( 'pre_get_posts', 'wpd_single_cpt_queries' );
  • Rewrite rules only handle incoming requests, show us the code you use to generate the URLs for your CPT. You also need to enforce the correct taxonomy term in your query for these posts. This answer might help you understand what parts are missing. – Milo Jan 20 '15 at 18:37
  • OK, will edit the question accordingly. I have posted a similar question before using a guest account but could not follow it up. – tim daniels Jan 21 '15 at 10:50
  • The likely issue is that you have hierarchical terms, you need a rewrite rule for each level of hierarchy. query var values like technology%2Ftablets will not work. – Milo Jan 22 '15 at 17:25
  • I don't understand, do I have to edit my rewrite rules completley ($newrules) or the function labelled wpd_single_cpt_queries, or both? – tim daniels Jan 23 '15 at 9:13
  • I've changed it to $newRules['my/(.+?)/(.+?)/(.+?)/?$'] = 'index.php?mycategory=$matches[1]&mycategory=$matches[2]&my=$matches[3]'; but nothing at all has changed. Like I said the rest of the site works fine but having a url such as "FAKECATEGORY/FAKECATEGORY/ipad" will show the same ipad page – tim daniels Jan 23 '15 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.