0
votes

Cheers,

for SEO reasons I try to remove the base slug of my custom hierachical service post type (example name: "custom-service"). These method is called SEO siloing. I tried different methods to achive the following url result.

How it shouldn't look:

https://foo.bar/custom-service/seo-agency/

https://foo.bar/custom-service/seo-agency/seo-workshop/

https://foo.bar/custom-service/foobar-agency/

https://foo.bar/custom-service/foobar-agency/foobar-workshop/

How it should look:

https://foo.bar/seo-agency/

https://foo.bar/seo-agency/seo-workshop/

https://foo.bar/foobar-agency/

https://foo.bar/foobar-agency/foobar-workshop/

I used following tutorials to realize these structure:

There are some people with the same problem:

At first I had implemented the solution of the first tutorial from Matthew Boynes. Everything is working except for my pagination. If I use these solution, my pagination stops working. Maybe the following code from the function add_rewrites() breaks the pagination:

add_permastruct( 'custom-service', "%custom-service%", array(
    'ep_mask' => EP_PERMALINK
));

You can't call the pages of my blog. The following urls stop working:

https://foo.bar/blog/page/2
https://foo.bar/cpt/page/2

In my second try I removed Matthew Boynes code. A blog without a pagination within its archive is useless. Then I've implemented the solution from "kellenmace.com". To make the code working for hierachical post types you have to modify the tutorials filter function for post_type_link:

function remove_custom_service_slug( $post_link, $post ) {
    if ( 'custom-service' === $post->post_type && 'publish' === $post->post_status ) {
        if( $post->post_parent ) {
            $parent = get_post($post->post_parent);
            $post_link = str_replace( '/' . $post->post_type . '/' . $parent->post_name . '/', '/', $post_link );
        } else {
            $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
        }
    }
    return $post_link;
}
add_filter( 'post_type_link', 'remove_custom_service_slug', 10, 2 );

But there is one big problem. It removes the base slug and the parent service slug:

https://foo.bar/seo-agency/

https://foo.bar/seo-workshop/

Its a bit frustrating. Maybe someone have experience with removing the base slug of an hierarchical post type and a good hint for my project.


If you have any questions, or if you would like further information or code, please don't hesitate to contact me.

Thanks for reading my question!

1

1 Answers

0
votes

Change the function to this to account for all cases:

Try this code,

function change_slug_struct( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'single-link', 'page' ) );
    } elseif ( ! empty( $query->query['pagename'] ) && false === strpos( $query->query['pagename'], '/' ) ) {
        $query->set( 'post_type', array( 'post', 'single-link', 'page' ) );

        // We also need to set the name query var since redirect_guess_404_permalink() relies on it.
        $query->set( 'name', $query->query['pagename'] );
    }
}
add_action( 'pre_get_posts', 'change_slug_struct' );