Search code examples
wordpress.htaccessurlcustom-post-type

how to remove custom post type from wordpress url?


I have a wordpress website which is using the custom template with custom post types like landing and services.

Each post type have a specific slug in the url like this => (http://example.com/landing/landing-page-name)

I want to change this url (http://example.com/landing/landing-page-name) to this url (http://example.com/landing-page-name).

In fact I need to remove the [landing] phrase from the url. The important thing is that the [landing] is a custom post type in my posts table.

I have tested following solutions:

==> I have changed slug to '/' in rewrite property in register_post_type() --> It breaks the all of landings, posts and pages url (404)

==> I added 'with_front' => false to the rewrite property --> nothing changed

==> I tried to do this with RewriteRule in htaccess --> it did not work or give too many redirects error

I could not get a proper result.

Did anyone solve this problem before?


Solution

  • First, you need to filter the permalink for your custom post type so that all published posts don't have the slug in their URLs:

    function stackoverflow_remove_cpt_slug( $post_link, $post ) {
        if ( 'landing' === $post->post_type && 'publish' === $post->post_status ) {
            $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
        }
        return $post_link;
    }
    add_filter( 'post_type_link', 'stackoverflow_remove_cpt_slug', 10, 2 );
    

    At this point, trying to view the link would result in a 404 (Page Not Found) error. That's because WordPress only knows that Posts and Pages can have URLs like domain.com/post-name/ or domain.com/page-name/. We need to teach it that our custom post type's posts can also have URLs like domain.com/cpt-post-name/.

    function stackoverflow_add_cpt_post_names_to_main_query( $query ) {
        // Return if this is not the main query.
        if ( ! $query->is_main_query() ) {
            return;
        }
        // Return if this query doesn't match our very specific rewrite rule.
        if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
            return;
        }
        // Return if we're not querying based on the post name.
        if ( empty( $query->query['name'] ) ) {
            return;
        }
        // Add CPT to the list of post types WP will include when it queries based on the post name.
        $query->set( 'post_type', array( 'post', 'page', 'landing' ) );
    }
    add_action( 'pre_get_posts', 'stackoverflow_add_cpt_post_names_to_main_query' );