0

I've tried this wonderful solution (solution below, original post here) for removing the slug from a custom post type, but unfortunately it causes a 404 error for blog posts when the blog slug is removed from post URLs. I've narrowed the issue down to the custom rewrite rules found in step 2, but I'm not sure what needs changing/adding/removing to get it working. Anyone have a remedy?

Solution Used:

Step 1: Disable rewrites on your custom post type by setting rewrites to 'false' when you register the post:

register_post_type( 'custom_post_type',
    array(
        'rewrite' => false
    )
);

Step 2: Manually add our custom rewrites to the bottom of the WordPress rewrites for our custom_post_type

function custom_post_type_rewrites() {
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/embed/?$', 'index.php?custom_post_type=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/trackback/?$', 'index.php?custom_post_type=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '([^/]+)/page/?([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&paged=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)(?:/([0-9]+))?/?$', 'index.php?custom_post_type=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
}
add_action( 'init', 'custom_post_type_rewrites' );

Step 3: Make permalinks to your custom post type 'pretty' again

function custom_post_type_permalinks( $post_link, $post, $leavename ) {
    if ( isset( $post->post_type ) && 'custom_post_type' == $post->post_type ) {
        $post_link = home_url( $post->post_name );
    }

    return $post_link;
}
add_filter( 'post_type_link', 'custom_post_type_permalinks', 10, 3 );

Step 4: Prevent duplicate post slugs

function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
    $check_post_types = array(
        'post',
        'page',
        'custom_post_type'
    );

    if ( ! in_array( $post_type, $check_post_types ) ) {
        return $slug;
    }

    if ( 'custom_post_type' == $post_type ) {
        // Saving a custom_post_type post, check for duplicates in POST or PAGE post types
        $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
        $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );

        if ( $post_match || $page_match ) {
            $slug .= '-duplicate';
        }
    } else {
        // Saving a POST or PAGE, check for duplicates in custom_post_type post type
        $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', 'custom_post_type' );

        if ( $custom_post_type_match ) {
            $slug .= '-duplicate';
        }
    }

    return $slug;
}
add_filter( 'wp_unique_post_slug', 'prevent_slug_duplicates', 10, 6 );
  • is there anyone out there who can answer this, I am having a same problem – Francis Alvin Tan Jan 23 at 12:50
0

Solution below. Replace "custom_post" with your custom post type.

add_action( 'init', 'init_post_types' );
function init_post_types() {
    register_post_type( 'custom_post',
        array(
            'labels' => array(
                'name' => __( 'Custom Posts' ),
                'singular_name' => __( 'Custom Post' ),
                'add_new_item' => __( 'Add New Custom Post' ),
                'edit_item' => __( 'Edit Custom Post' ),
                'new_item' => __( 'New Custom Post' ),
                'view_item' => __( 'View Custom Post' ),
                'search_items' => __( 'Search Custom Post' ),
                'not_found' => __( 'No custom posts found' ),
                'not_found_in_trash' => __( 'No custom posts found in Trash' )
            ),
            'menu_position' => 21,
            'public' => true,
            'has_archive' => false,
            'supports' => array(
                'title',
                'editor',
                'thumbnail'
            ),
            'rewrite' => array(
                'with_front' => false,
                'slug' => false, // SET SLUG TO FALSE
            ),
            'exclude_from_search' => true,
            'register_meta_box_cb' => 'add_location_metabox'
        )
    );
}

/**
 * Remove the slug from published post permalinks. Only affects our custom post type, though.
 */

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

function gp_add_cpt_post_names_to_main_query( $query ) {
    // Bail if this is not the main query.
    if ( ! $query->is_main_query() ) {
        return;
    }
    // Bail if this query doesn't match our very specific rewrite rule.
    if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
        return;
    }
    // Bail 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', 'custom_post' ) );
}
add_action( 'pre_get_posts', 'gp_add_cpt_post_names_to_main_query' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.