0

I know you can't have:

/my-cpt1/name-of-post-1/

and

/my-cpt2/name-of-post-2/

both live at:

/my-ideal-root/name-of-post-1/
/my-ideal-root/name-of-post-2/

But I have a situation where I have content that must be differentiated into different custom post types (because of where it is used elsewhere), that I would like to also be represented on the front end as living under one root path, let's say that's /rules/. Let's also say that I can guarantee /rules/ won't be occupied by anything else (that is, I won't put a page there or any other content under it).

Is it possible to somehow redirect:

/my-cpt1/name-of-post-a/
/my-cpt2/name-of-post-b/
/my-cpt3/name-of-post-c/
...

and so on to:

/potato/name-of-post-a/
/potato/name-of-post-b/
/potato/name-of-post-c/

Maybe after each CPT resolves to its default URL /my-cpt-1/whatever/, I can redirect it to the /rules/my-cpt-1/whatever, and render content in a template at that path, pulling the data based on /whatever/ from the correct CPT (/my-cpt-1/) in the path?

1 Answer 1

0

You can have two CPT under a common "prefix"

/potato/name-of-post-from-CPT_1
/potato/name-of-post-from-CPT_2

but you need to create custom rewrite rules and change links generated by WP for these CPTs.

Links created for CPT can be changed with post_type_link filter. Before changing the link, check what format is in use, "plain" (http://example.com/?p=N) or "pretty permalinks" (http://example.com/page-name/).

add_filter( 'post_type_link', 'se390940_oneslug_permalinks', 10, 3 );

function se390940_permalinks( $permalink, $post, $leavename )
{
    global $wp_rewrite;

    if ( !$wp_rewrite->using_permalinks() )
        return $permalink;
    //
    // apply changes to my CPTs only
    $cpts = ['my-cpt1', 'my-cpt2'];
    if ( !in_array( $post->post_type, $cpts ) )
        return $permalink;

    return home_url( "/potato/{$post->post_name}/" );
}

Now you need to add rewrite rules to recognize new links and display relevant posts.
This fragment post_type[]=my-cpt1&post_type[]=my-cpt2 means that post_type is an array with two values and causes post search in both types.

add_action( 'init', 'se390940_oneslug_rewrite' );

function se390940_oneslug_rewrite()
{
    // archive page
    add_rewrite_rule(
        'potato(?:/([0-9]+))?/?$',
        'index.php?post_type[]=my-cpt1&post_type[]=my-cpt2&paged=$matches[1]',
        'top'
    );
    // CPT single page
    add_rewrite_rule(
        'potato/([^/]+)(?:/([0-9]+))?/?$',
        'index.php?post_type[]=my-cpt1&post_type[]=my-cpt2&name=$matches[1]&page=$matches[2]',
        'top'
    );
}

To make rewrite rules work, you have to click Save in Dashboard -> Settings -> Permalinks or use flush_rewrite_fules() when switching the theme ("important note")

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.