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

I have created hierarchy based custom permalinks with the help of this link, but now it is causing a 404 error on another custom taxonomy used in the site. I want custom permalinks on this other taxonomy also, but if I don’t use any rewrite arguments and leave it on its default permalink, it is still not working.

My code for the second taxonomy:

Read More
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',
        'register_meta_box_cb' => 'add_gallery_metaboxes'
    )
);
register_taxonomy(
    'gallery_category',
    'gallery',
    array(
        'hierarchical' => true,
        'labels'       => $labels
    )
);

And here is my first custom taxonomy 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'       => '%article_category%/articles',
            'with_front' => true
        ),
        'has_archive'          => '%article_category%',
        'register_meta_box_cb' => 'add_article_metaboxes'
    )
);
register_taxonomy(
    'article_category',
    'article',
    array(
        'hierarchical' => true,
        'labels'       => $labels,
        'query_var'    => true,
        'rewrite'      => array( 'slug' => '', 'hierarchical' => true ),
    )
);

Function for custom permalink:

function filter_post_type_link( $link, $post ) {
    if ( $post->post_type != 'article' )
        return $link;
    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, '/', true ), $link ); // See custom function defined below
    }
    return $link;
}
add_filter( 'post_type_link', 'filter_post_type_link', 10, 2 );

Related posts

1 comment

  1. 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, '/', 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, '/', 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 = '/', $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;    
    }
    

Comments are closed.