WPSurfer.com

Remove Custom Post Type Slug from URL in WordPress

Published on June 18, 2023 | Updated on June 29, 2023

Custom post types are a powerful feature in WordPress that allows you to create and manage different types of content beyond regular blog posts and pages.

However, there might be situations where you want to remove a custom post type from the URL structure.

In this guide, we’ll explore the process of removing a custom post type from a URL in WordPress.

How to Remove Custom Post Type Slug from URL in WordPress

Before making any changes to your website, it’s crucial to create a backup. This ensures that you can restore your website in case anything goes wrong during the process.

Add this code to your functions.php file or use a code snippet plugin to take care of the headache.

final class My_Remove_Post_Type_Slugs {

    /**
     * Define our $types variable.
     */
    protected $types = [];

    /**
     * Constructor.
     */
    public function __construct() {

        // CHANGE THIS ARRAY
        $this->types = [
            'portfolio' => 'portfolio-item',
        ];

        add_filter( 'post_type_link', [ $this, 'post_type_link' ], 10, 3 );
        add_action( 'pre_get_posts', [ $this, 'parse_request' ] );
        add_action( 'template_redirect', [ $this, 'template_redirect' ] );
    }

    /**
     * Remove the post type name from the post type link.
     */
    public function post_type_link( $post_link, $post, $leavename ) {
        $post_type = $post->post_type;

        if ( ! array_key_exists( $post_type, $this->types ) || 'publish' !== $post->post_status ) {
            return $post_link;
        }

        $post_link = str_replace( '/' . $this->types[$post_type] . '/', '/', $post_link );

        return $post_link;
    }

    /**
     * Trick WordPress to allow our post types to render without a custom slug.
     */
    public function parse_request( $query ) {
        if ( ! $query->is_main_query() ) {
            return;
        }

        // Only noop our very specific rewrite rule match.
        if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
            return;
        }

        // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match.
        if ( ! empty( $query->query['name'] ) ) {
            $array = [ 'post', 'page' ];
            $array = array_merge( $array, array_keys( $this->types ) );
            $query->set( 'post_type', $array );
        }
    }

    /**
     * Redirect the old URL's with the slugs.
     */
    public function template_redirect() {
        if ( is_admin() || is_preview() || ! is_singular( array_keys( $this->types ) ) ) {
            return;
        }
        $post_permalink = trailingslashit( get_permalink() );
        $current_url    = trailingslashit( $this->get_current_url() );
        $post_slug      = get_post_field( 'post_name', get_post() );
        if ( ( $post_permalink && $current_url )
            && ( $post_permalink !== $current_url )
            && ( false !== strpos( $post_permalink, $post_slug ) && false !== strpos( $current_url, $post_slug ) )
        ) {
            wp_safe_redirect( $post_permalink, 301 );
            exit;
        }
    }

    /**
     * Get the current URL helper method.
     */
    protected function get_current_url() {
        global $wp;
        if ( $wp ) {
            return home_url( add_query_arg( [], $wp->request ) );
        }
    }

}
new My_Remove_Post_Type_Slugs;

Identify the custom post type that you want to remove from the URL structure. You will need the name or slug of the custom post type for the next steps.

Make sure to add the actual name or slug of your custom post type

 // CHANGE THIS ARRAY
        $this->types = [
            'speed => 'speed',
        ];

Since it is very likely that you have more than one custom post type, add more lines to it

 // CHANGE THIS ARRAY
        $this->types = [
            'speed => 'speed',
            'seo => 'seo',
        ];
Manuel Campos

Manuel Campos

I am José Manuel. I am writing about things I know and things that I am learning about WordPress. I hope you find the content of this blog useful.