[SOLVED] Display CPT list page (archive) with category term on slug


This Content is from Stack Overflow. Question asked by John Snow Dad

I’m starting my studies with wordpress and I have a project that will be organized by categories. It’s basically a news site. Example:

  • mysite.com/sports/news/post-name
  • mysite.com/sports/review/post-name
  • mysite.com/health/news/post-name
  • mysite.com/health/review/post-name


  • 1 – “sports” and “health” are categories.
  • 2 – “news” and “review” are subcategories (with repeated names and slugs, which is already a problem in wordpress).
  • 3 – “post-name” are the posts.


  • mysite.com/sports > will show listings for “news” and “review”
  • mysite.com/health > will show listings for “news” and “review”
  • mysite.com/sports/news/ > will list “news” records
  • mysite.com/sports/review/ > will list “review” records
  • mysite.com/sports/news/post-name > Will show the post
  • mysite.com/sports/review/post-name > Will show the post

I’m having a hard time structuring my site this way. In my research I found a PAID plugin that might help: Permalink Manager Pro. Does it resolve these issues? Is there another way?


In that link I found the following solution:

The solution for me had three parts. In my case the post type is called trainings.

  1. Add 'rewrite' => array('slug' => 'trainings/%cat%') to the
    register_post_type function.
  2. Change the slug to have a dynamic
  3. category. "Listen" to the new dynamic URL and load the appropriate template.

So here is how to change the permalink dynamically for a given post type. Add to functions.php:

function vx_soon_training_post_link( $post_link, $id = 0 ) {
    $post = get_post( $id );
    if ( is_object( $post ) ) {
        $terms = wp_get_object_terms( $post->ID, 'training_cat' );
        if ( $terms ) {
            return str_replace( '%cat%', $terms[0]->slug, $post_link );

    return $post_link;

add_filter( 'post_type_link', 'vx_soon_training_post_link', 1, 3 );

…and this is how to load the appropriate template on the new dynamic URL. Add to functions.php:

function archive_rewrite_rules() {
    //flush_rewrite_rules(); // use only once

add_action( 'init', 'archive_rewrite_rules' );

Thats it! Remember to refresh the permalinks by saving the permalinks again in de backend. Or use the flush_rewrite_rules() function.

But I have a question that I couldn’t do there:

This part:

Add 'rewrite' => array('slug' => 'trainings/%cat%') to the register_post_type function.

where do I do that? Or is this already embedded in the later code?

This Question was asked in StackOverflow by John Snow Dad and Answered by John Snow Dad It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?