Question 1 Permalink structure

I trying to implement the right url/permalink structure for my site, but I can't get it to work.

I have the following setup:

Custom post type: training

  register_post_type( 'training',
        'labels' => array(
            'name' => __( 'Trainingen' ),
            'singular_name' => __( 'Training' ),
            'all_items'           => __( 'Alle trainingen' ),
            'view_item'           => __( 'Bekijk training' ),
            'add_new_item'        => __( 'Nieuwe training' ),
            'add_new'             => __( 'Nieuwe training' )
        'public' => true,
        'has_archive' => true,
        'hierarchical' => false,
        'rewrite' => array('slug' => 'our-training', 'with_front' => false),
        'show_in_rest' => true
**Custom taxonomy : training-category**
    $args = array(
        "label" => ( "training category"),
        "labels" => $labels,
        "rewrite" => array( 'slug' => 'training-category', 'with_front' => true, ),
        "show_admin_column" => true,
        "hierarchical" => false,
        "has_archive" => true,
        "show_ui" => true
    register_taxonomy( "training_category", array( "event", "post", "training", "employee"), $args );

The permalink structure I want to establish:


what I do get is:


So the custom taxonomy is not inserted correctly in the permalink.

(I am also using Yoast breadcrumbs and have set the taxonomy to show for the training cpt to: training-category (my custom tax).)

Any tips on how I can get the desired permalink structure?

Question 2 - Redirect

Secondly I use facetwp for filtering so I need to redirect the category archive to a facetwp archive page. Redirect I want to establish (simplyfied):


must redirect to:


How can I do this the best way?

Any pointers in the right direction will be highly appreciated!

  • 1
    Set the with_front key to TRUE in your CPT arguments. That should help with question 1 Commented Jul 8, 2021 at 10:46
  • Thanks a lot Nathan, that seems to work. Commented Jul 10, 2021 at 7:27

1 Answer 1


There was a problem with archive page and pagination in the original answer. Therefore, instead of changing the "rewrite" => ['slug' => 'our-training/%training-category%'] in register_post_type() as I suggested earlier, add the following rewrite rules and change the links created for CPT.

The rules will handle such addresses:

  • display single training post with pagination support
  • display training posts assigned to training-category-1 (uncomment first rewrite rule) note: this is query for taxonomy term, not cpt, so the first available template from the list will be used: taxonomy-training_category.php > taxonomy.php > archive.php

Default rules will handle:

  • display all training posts (archive)
  • display all posts (any type, "event", "employee", etc.) assigned to training-category-1

This code worked for me.

add_action( 'init', 'se391612_cpt_permalink', 20 );
add_filter( 'post_type_link', 'se391612_term_in_cpt_link', 20, 4 );

function se391612_cpt_permalink()
    // CPT posts from custom taxonomy term (term archive)
    //    'our-training/([^/]+)(?:/page/?([0-9]+))?/?$', 
    //    'index.php?post_type=training&training_category=$matches[1]&paged=$matches[2]',
    //    'top'
    // single post with pagination 

function se391612_term_in_cpt_link( $post_link, $post, $leavename, $sample )
    if ( ! $post instanceof \WP_Post || 'training' != $post->post_type)
        return $post_link;
    $new_link = $post_link;
    $all_terms = wp_get_post_terms( $post->ID, 'training_category', [
        'hide_empty' => '0',
        'fields' => 'slugs',
        'orderby' => 'term_id',
    ] );
    if ( !is_array($all_terms) || 0 == count($all_terms) )
        return $post_link;

    $term = array_shift($all_terms) . '/';
    $new_link = str_replace('our-training/', 'our-training/'.$term, $new_link);

    return $new_link;

Important note:
If you uncomment the first add_rewrite_rule() to support /our-training/training-category-1 permalink format, an address collision will occur. For WP there is no difference between these addresses, how it interprets them depends on the order of rewrite rules.

/our-training/training-category-1   // all "training" post from category "training-category-1"
/our-training/some-training-name    // single "training" post

However, if you would like both address types to work and you know that there will be only several categories, you can add these categories in the rules (manually or automatically).

post_type_link filter

  • Hi thanks a lot for this answer. This is helping a lot, and it works for our-training/training-category-1/training-name-3 and our-training/training-category-1/ but I get a 404 on our-training/ even though there is an archive-training.php which I don't understand. Commented Jul 10, 2021 at 7:28
  • Oh I actually got this to work with another rewrite rule: $new['training/?$'] = 'index.php?xpost_type=training'; All permalinks seem to be working fine now, I'll be having a go at sorting the breadcrumbs out now. Thanks for your input! Commented Jul 10, 2021 at 7:40

Your Answer

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

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