2

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:

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 );
5
  • Have you flushed the rewrite rules?
    – s_ha_dum
    May 28, 2013 at 14:30
  • Yes I did it by reloading the settings->permalinks page.
    – Noman
    May 28, 2013 at 14:36
  • If I remove the rewrite attribute from first custom taxonomy then both work fine but custom permalinks stop.
    – Noman
    May 28, 2013 at 14:37
  • You mention two custom taxonomies. Post the registration code for both. Post your code that you based off of the other question you linked to.
    – s_ha_dum
    May 28, 2013 at 14:38
  • Okay added the code for first custom taxonomy in question.
    – Noman
    May 28, 2013 at 14:45

1 Answer 1

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;    
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.