Remove Slug from Custom Post Type

I was wondering how i can remove the prefix from the slugs of custom post types using htaccess rules or any other appropriate method.

Currently my custom post types look like this:

Read More
http://www.domain.com/os_estate/5-bedroom-property-for-sale

and i would simply like this to be:

http://www.domain.com/5-bedroom-property-for-sale

I was able to achieve this via a plugin but it significantly added to the page load time..

My common settings in Permalinks is set to “Post Name”

Related posts

3 comments

  1. There is a simpler and lighter solution:

    First: set the slug argument for your custom post type to ‘/’ when registering the post type:

    add_action( 'init', 'register_my_post_type' );
    function register_my_post_type() {
        $args = array(
                //The rest of arguments you are currently using goes here
                'rewrite'    => array(
                                 'slug' => '/'
                                 )
         );
         register_post_type( 'my-post-type', $args );   
    }
    

    Second: in preg_get_posts() action hook include your post type in the query when only the $query->query['name'] is present:

    add_action( 'pre_get_posts', 'wpse_include_my_post_type_in_query' );
    function wpse_include_my_post_type_in_query( $query ) {
    
         // Only noop the main 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;
    
          // Include my post type in the query
         if ( ! empty( $query->query['name'] ) )
              $query->set( 'post_type', array( 'post', 'page', 'my-post-type' ) );
     }
    

    Third: I’ve found that in some situations there are conflicts with pages and single posts. I’ve been able to avoid this conflict by checking if a page with the request name exists and overriding the query conditionals but I’m not sure if more conflict can happens:

    add_action( 'parse_query', 'wpse_parse_query' );
    function wpse_parse_query( $wp_query ) {
    
        if( get_page_by_path($wp_query->query_vars['name']) ) {
            $wp_query->is_single = false;
            $wp_query->is_page = true;
        }
    
    }
    

    IMPORTANT: You need to flush the rewrite rules. You can do it by viviting the permalink options page in the admin area. This is needed because we are registering a new rewrite rule, so the current rewrite rules stored in the database must be regenerated.

  2. // Well then, first use a function to mention your custom post types.

    function my_custom_post_types(){
        return array(
            'os_estate', 
            'os_villas', 
            'os_chalets', 
            'os_cottages'
        );
    }
    

    // Then, filtering the request.

        add_action( 'parse_request','my_custom_post_types_parse_request', 999);
    
    function my_custom_post_types_parse_request( $query ){
    
        if( isset($query->request) )
        {
            $req = explode('/', ltrim($query->request,'/'));
            if( !is_admin() && isset($req['0']) )
            {
                global $wpdb;
                $name = stripslashes($req['0']);
                $_post = $wpdb->get_row( "SELECT * FROM $wpdb->posts WHERE post_status = 'publish' AND post_name ='". $name ."' AND post_type IN ('" . join("', '", my_custom_post_types() ) . "')" );
    
                if( $_post )
                {
                    $query->query_vars['error'] = '';
                    $query->query_vars['post_type'] = $_post->post_type;
                    $query->query_vars['name'] = $name;
                }
            }
        }
    }
    

    // And next filter all the desired post types link.

    add_filter( 'post_type_link', 'my_custom_post_types_permalink', 10, 2);
    
    function my_custom_post_types_permalink( $post_link, $post ){
        if( in_array( $post->post_type, my_custom_post_types() ) && !empty($post->post_name) && $post->post_status == 'publish' && '' != get_option('permalink_structure') )
        {
            $post_name = $post->post_name;
            $post_link = home_url("/$post_name/");
        }
        return $post_link;
    }
    

    EDIT: fixed errors, adding this line due to edit 6 chars minimum requirement

  3. I think that you just need to put rewrite rule in your code in place where you register post type.

    Just place this code

    $rewrite = array(
        'slug'                => '',
        'with_front'          => true,
        'pages'               => true,
        'feeds'               => true,
        );
    

    after the $labels array();

    and before $args = array();

Comments are closed.