Shouldn’t this be easy?! Custom post type/custom taxonomy permalink

So this is driving me absolutely insane. I’ve spend days trying to fix this and I can’t work out why this is so difficult as surely this is a very common permalink structure!

I looked through hundreds of answers and posts and none of them seem to solve the problem.

I simply want this structure:

mysite.com/custom-post-type/custom-taxonomy-term/post-name

So I achieve the following:

mysite.com/literature - all literature posts
mysite.com/literature/fiction - all literature posts with 'fiction' term
mysite.com/literature/fiction/mybook - the post

Every time I try something I get 404 errors or the pagnination doesn’t work.

I don’t understand why this is so hard!

Any help really appreciated!

Thank you

======================================================
==================ADDITIONAL INFORMATION==================

Currently I’m registering the post type and taxonomy as follows:

register_post_type('literature',$args);
'rewrite' => array('slug' => 'literature/books','with_front' => false),

register_taxonomy('literature_category',array('literature'), array(
'rewrite' => array( 'slug' => 'literature','with_front' => false ),

If I register both as ‘literature’ I get a 404 on the mysite.com/literature page but this displays my permalink as: mysite.com/literature/books/mybook

After following the advice on this question – Custom post types, taxonomies, and permalinks

I’ve added this to my functions:

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

    if ($cats = get_the_terms($post->ID, 'literature_category'))
        $link = str_replace('%literature_category%', array_pop($cats)->slug, $link);
    return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);

And changed my post type to 'slug' => 'literature/%literature_category%'
And changed my taxonomy to 'slug' => 'literature'

This works great except that on mysite.com/literature pagination doesn’t work so I get a 404 error on the following url:

mysite.com/literature/page/2/

1

Follow the advice on this question as you did already, but add this to your code:

add_action( 'generate_rewrite_rules', 'fix_literature_category_pagination' );
function fix_literature_category_pagination( $wp_rewrite ) {
    unset($wp_rewrite->rules['literature/([^/]+)/page/?([0-9]{1,})/?$']);
    $wp_rewrite->rules = array(
        'literature/?$' => $wp_rewrite->index . '?post_type=literature',
        'literature/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?post_type=literature&paged=' . $wp_rewrite->preg_index( 1 ),
        'literature/([^/]+)/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?literature_category=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 2 ),
    ) + $wp_rewrite->rules;
}

Lastly, go to Settings > Permalinks and hit save. If it still doesn’t work, save your permalinks again. Sometimes I feel like you have to save ’em twice, but who knows. Anyway, Let me know how you make out. Note that Computer Science Standard #1 applies: It Works For Me… 😉

From the land of TMI…

For reference, the reason why the pages don’t work by default is that WordPress puts in a rewrite rule for literature/%literature_category%/%book%/%page%, which makes total sense if you think about it. So your default permalinks have these competing rules in this order:

[literature/([^/]+)/([^/]+)(/[0-9]+)?/?$] => index.php?literature_category=$matches[1]&book=$matches[2]&page=$matches[3]
[literature/([^/]+)/page/?([0-9]{1,})/?$] => index.php?literature_category=$matches[1]&paged=$matches[2]

All we’re really doing here is changing the order of these by unsetting the latter (we can keep it in, but then every rewrite thereafter has one more regex to run on page load) and adding it to the beginning of the array.

Fun fact: If you ever have a “book” entitled “page” and it has multiple pages, this order will conflict and its subsequent pages won’t work!

Leave a Comment