Custom Post Type Slug clash
Asked Answered
B

1

7

I have multiple custom post types with custom taxonomies. I'm having a slug clash despite of having different parents.

Here is my URL structure: /work/%client_name%/%project_name%

I have a client (client1) and project (some-cool-project-name) that generates this slug: "/work/client1/some-cool-project-name".

When I create a new post under a different parent (client) and give the same name (and slug) to the post, wordpress appends -2 to the slug: "/work/client2/some-cool-project-name-2"

Custom post type as:

// Custom taxonomies.
function custom_taxonomies() {
    $args = array(
        'label' => __( 'Work', '' ),
        'labels' => array(
            'name' => __( 'Work', '' ),
            'singular_name' => __( 'Work', '' ),
        ),
        'description' => '',
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'show_in_rest' => false,
        'rest_base' => '',
        'has_archive' => true,
        'show_in_menu' => true,
        'exclude_from_search' => false,
        'capability_type' => 'post',
        'map_meta_cap' => true,
        'hierarchical' => true,
        'rewrite' => array( 'slug' => 'work/%client_name%', 'with_front' => true ),
        'query_var' => true,
        'menu_icon' => 'dashicons-hammer',
        'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'page-attributes' ),
        'taxonomies' => array( 'client_name' ),
    );
    register_post_type( 'work', $args );

    $args = array(
        'label' => __( 'Clients', '' ),
        'labels' => array(
            'name' => __( 'Clients', '' ),
            'singular_name' => __( 'Client', '' ),
        ),
        'public' => true,
        'hierarchical' => false,
        'label' => 'Clients',
        'show_ui' => true,
        'show_in_menu' => true,
        'show_in_nav_menus' => true,
        'query_var' => true,
        'rewrite' => array( 'slug' => 'work/client_name', 'with_front' => false, ),
        'show_admin_column' => false,
        'show_in_rest' => false,
        'rest_base' => '',
        'show_in_quick_edit' => false,
    );
    register_taxonomy( 'client_name', array( 'work' ), $args );
}
add_action( 'init', 'custom_taxonomies' );

And my permalink rewrite:

// Replace URL with proper taxonomy structure.
function permalink_rewrites( $link, $post ) {
    if ( $post->post_status !== 'publish' || $post->post_type != 'work' ) {
        return $link;
    }

    if ( $post->post_type == 'work' ) {
        $type = '%client_name%/';
        $filters = get_the_terms( $post->ID, 'client_name' );
        $slug = $filters[0]->slug . '/';
    }

    if ( isset( $slug ) ) {
        $link = str_replace( $type, $slug, $link );
    }

    return $link;
}
add_filter( 'post_type_link', 'permalink_rewrites', 10, 2 );

Any suggestions on what I can do this fix this?

Thanks.

Belike answered 13/6, 2018 at 21:44 Comment(1)
In wordpress any post, taxonomy, custom post type , pages etc all must have unique slugs, wordpress never allow to create the page and post with same slug.Barbey
T
4

Unfortunately WordPress isn't really designed this way. Part of why this doesn't work for 2 Posts/CPTs even in separate categories, is what happens when one is in both categories? You'd have to start getting some nasty rewrite rules and the redirect_canonical() function involved - at which point you're just asking for 404 errors out the wazoo.

Luckily, instead of relying on taxonomies and CPTs with the same slug, there is something you could do. You could instead drop the taxonomy part of it and use the hierarchical format of your custom post type.

Part of why this works is because you can't assign multiple parents to one post/CPT, so there are no permastruct clashes.

Create a new "Work" called Client 1 and a second called Client 2.

Now, with those "parent works" created, you can create a third "Work" called Cool Project and set the Parent to Client 1, and then create fourth called Cool Project as well and set the parent to Client 2.

This will give you the following permalink structure:

https://example.com/work/client-1/cool-project
https://example.com/work/client-2/cool-project

You can see this in action right now here:

These are set up exactly the way I mentioned:

The downside of this is, is that if you use the /work/client-name page to display anything, you'll now have to set up a Post Type Template (Available since WP 4.7.0) to achieve the functionality that you have with the archive template instead.

However it prevents the need for redirects and rewrite rules.

Here's a screenshot of the permalink structure: Here's a screenshot of the permalink structure

Here's a screenshot of the CPT Overview admin page: Here's a screenshot of the CPT Overview admin page

Trenttrento answered 18/6, 2018 at 23:53 Comment(4)
Thanks for your response @Xhynk. Could you elaborate on "drop the taxonomy part of it and use the hierarchical format of your custom post type"? I can see how this could work. But it seems to be too ugly. :( Is this the only way?Belike
Sure - right now you're relying on a taxonomy (client_name) for the permalink. So you have example.com/client-1/project-1. In order to have "Cool Project" with the slug "cool-project" on both Client 1 & 2, you can not use the taxonomy like that in the permalink structure. I wouldn't say it's ugly, as example.com/parent/child is an extremely common naming convention, even if it's not your desired example.com/taxonomy/post. You in order to have the same post name and slug, you can't rely on the taxonomy for the permalink, and instead need to use a parent post.Trenttrento
The "ugliest" part is that you'll need to create "Client 1" and "Client 2" as "projects", but I think it still has some semblance of order. Unfortunately WordPress isn't really designed around having the same post slug in more than one placeTrenttrento
Thanks for your explanation. @TrenttrentoBelike

© 2022 - 2024 — McMap. All rights reserved.