Change in custom taxonomy permalink causes 404 error for another custom taxonomy

After many efforts I have solved it, but it’s not completely what I want, as I had to compromise on one thing and passed some separators in the URL. Example:

example.com/separator1/parentatx/childtax/separator2/postname/

In order to avoid 404 errors, in case of pagination and another custom taxonomy, I created some rewrite rules. Here is my code:

First post type and custom taxonomy registration code:

register_post_type( 
    'article',
    array(
        'public'        => true,
        'hierarchical'  => true,
        'menu_position' => 15,
        'supports'      => array( 'title', 'editor', 'comments', 'thumbnail' ),
        'taxonomies'    => array( '' ),
        'menu_icon'     => get_template_directory_uri().'/img/icon_article.png',
        'query_var'     => true                              
        'rewrite'       => array(
            'slug'       => 'articles/%article_category%/topic/',
            'with_front' => true
        ),
        'has_archive'          => '/all-articles/',
        'register_meta_box_cb' => 'add_article_metaboxes'
    )
);
register_taxonomy( 
    'article_category',
    'article',
    array(
        'hierarchical' => true,
        'labels'       => $labels,
        'query_var'    => true,
        'rewrite'      => array( 'slug' => '/articles/', 'hierarchical' => true ),
    )
);

In the first custom taxonomy, I used ‘articles’ and ‘topic’ as separators; you can use any according to your scenario.

Second post type and custom taxonomy registration code:

register_post_type( 
    'gallery',
    array(
        'public'        => true,
        'menu_position' => 15,
        'supports'      => array( 'title', 'editor', 'comments', 'thumbnail' ),
        'taxonomies'    => array( '' ),
        'menu_icon'     => get_template_directory_uri().'/img/icon_gallery.png',
        'query_var'     => true,
        'rewrite'       => array(
            'slug'       => 'galleries/%gallery_category%/images/',
            'with_front' => true
        ),
        'has_archive'          => '/all-galleries/',
        'register_meta_box_cb' => 'add_gallery_metaboxes'
    )
);

In the second custom taxonomy, I used ‘galleries’ and ‘images’ as separators; you can use any according to your scenario.

The function for rewrite rules:

add_filter( 'rewrite_rules_array', 'mmp_rewrite_rules' );
function mmp_rewrite_rules( $rules ) {
    $newRules  = array();
    //Rules for First Taxonomy
    $newRules['articles/(.+)/(.+)/(topic)/(.+)/?$'] = 'index.php?article=$matches[4]'; 
    $newRules['articles/(.+)/(topic)/(.+)/?$'] = 'index.php?article_category=$matches[1]&article=$matches[3]';
    $newRules['articles/(.+)/(.+)/?([0-9]{1,})/?$'] = 'index.php?article_category=$matches[1]&page=$matches[3]';
    $newRules['articles/(.+)/(.+)/(page)/?([0-9]{1,})/?$'] = 'index.php?article_category=$matches[1]&page=$matches[4]';
    $newRules['articles/(.+)/?$'] = 'index.php?article_category=$matches[1]';
    //Rules for Second Taxonomy
    $newRules['galleries/(.+)/(.+)/(images)/(.+)/?$'] = 'index.php?gallery=$matches[4]'; 
    $newRules['galleries/(.+)/(images)/(.+)/?$'] = 'index.php?gallery_category=$matches[1]&gallery=$matches[3]';
    $newRules['galleries/(.+)/(.+)/?([0-9]{1,})/?$'] = 'index.php?gallery_category=$matches[1]&page=$matches[3]';
    $newRules['galleries/(.+)/(.+)/(page)/?([0-9]{1,})/?$'] = 'index.php?gallery_category=$matches[1]&page=$matches[4]';
    $newRules['galleries/(.+)/?$'] = 'index.php?gallery_category=$matches[1]'; 

    return array_merge( $newRules, $rules );
}

The functions to change the custom post type URL according to custom taxonomy hierarchy:

function filter_post_type_link( $link, $post ) {
    if ( $post->post_type != 'article' && $post->post_type != 'gallery' )
        return $link;       
    if ( $post->post_type == 'article' ) {
        if ( $cats = get_the_terms( $post->ID, 'article_category' ) ) {
            $link = str_replace( '%article_category%', get_taxonomy_parents( array_pop( $cats )->term_id, 
                'article_category', false, "https://wordpress.stackexchange.com/", true ), $link ); // See custom function defined below
        }
        return $link;
    } elseif ( $post->post_type == 'gallery' ) {
        if ( $cats = get_the_terms( $post->ID, 'gallery_category' ) ) {
            $link = str_replace('%gallery_category%', get_taxonomy_parents( array_pop( $cats )->term_id, 
                'gallery_category', false, "https://wordpress.stackexchange.com/", true ), $link); // See custom function defined below
        }
        return $link;
    }
}
add_filter( 'post_type_link', 'filter_post_type_link', 10, 2 );

// My own function to do what get_category_parents does for other taxonomies
function get_taxonomy_parents( $id, $taxonomy, $link = false, $separator="https://wordpress.stackexchange.com/", $nicename = false, $visited = array() ) {
    $chain = '';   
    $parent = &get_term( $id, $taxonomy );
    if ( is_wp_error( $parent ) ) {
        return $parent;
    }
    if ( $nicename )    
        $name = $parent -> slug; 
    else    
        $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 ) {
        // Nothing, can't get this working :(
    } else {   
        $chain .= $name . $separator;    
    }
    return $chain;    
}

Leave a Comment