I create a custom post type:

$rewrite = array(
    'slug'                  => '%categories%',
    'with_front'            => false,
    'pages'                 => true,
    'feeds'                 => true,
$args = array(
     // ...Other options
    'taxonomies'            => array( 'categories' ),
    'hierarchical'          => false,
    'public'                => true,
    'has_archive'           => 'applications',      
    'publicly_queryable'    => true,
    'rewrite'               => $rewrite,
    // Other options...
register_post_type( 'applications', $args );

And the taxonomy:

$args = array(
     // ...Other options
    'hierarchical'               => true,
    'public'                     => true,
     // Other options...
register_taxonomy( 'categories', array( 'applications' ), $args );

and this function to add hierarchical taxonomy slug to post url:

function remove_cpt_slug( $post_link, $post ) {

    if ( 'applications' != $post->post_type || 'publish' != $post->post_status || strpos($post_link, '%categories%') === FALSE) {
        return $post_link;
    $terms = wp_get_object_terms( get_the_ID(), 'categories', array( 'fields' => 'slugs' ) );

    if ( !is_wp_error($terms) && !empty($terms) ){
            $taxurl = implode('/', $terms );
    } else {
        return str_replace( '%categories%/', '', $post_link );
    return str_replace( '%categories%', $taxurl , $post_link );

add_filter( 'post_type_link', 'remove_cpt_slug', 10, 2 );
add_filter( 'post_link', 'remove_cpt_slug', 10, 2 );

Now generated permalink for posts as I expected. But they redirect to %postname% structure and get 404 Not Found Error.

domain.com/game/puzzle/desert-storm/ will redirect to domain.com/desert-storm/

(After any change I save the permalink settings - flush rewrite)

How to prevent this redirect? and solve the 404?

1 Answer 1


The slug of a CPT can not be dynamic (actually no slug can be) as wordpress needs to know how to parse the URL very early in the handling of the request. You can probably change the behaviour, but you will only end with the same results that slugs have to be constant even when you implement your own parsing.

This is why your remove_cpt_slug generates the url you expect but wordpress fails to handle it correctly.

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.