Remove Slug from Custom Post Type results in 404

I am working on a plugin that creates lists. After creating a list, I wanted to remove the slug from the url

Post type:

$rewrite = [
        'slug'       => 'single-link',
        'with_front' => false,
        'pages'      => false,
        'feeds'      => false,
    ];
    $args    = [
        'label'               => esc_html__( 'Single Link', 'single-link' ),
        'labels'              => $labels,
        'supports'            => [ 'title' ],
        'hierarchical'        => false,
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_position'       => 15,
        'menu_icon'           => 'dashicons-admin-links',
        'show_in_admin_bar'   => false,
        'show_in_nav_menus'   => true,
        'can_export'          => true,
        'has_archive'         => false,
        'exclude_from_search' => true,
        'publicly_queryable'  => true,
        'rewrite'             => $rewrite,
        'capability_type'     => 'page',
        'show_in_rest'        => true,
    ];

    $args = apply_filters( 'single-link/post_type/args', $args );
    register_post_type( 'single-link', $args );

Remove the slug from the URL:

function remove_cpt_slug( $post_link, $post, $leavename ) {

if ( 'single-link' != $post->post_type || 'publish' != $post->post_status ) {
    return $post_link;
}

$post_link = str_replace( "https://wordpress.stackexchange.com/" . $post->post_type . "https://wordpress.stackexchange.com/", "https://wordpress.stackexchange.com/", $post_link );

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


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' ) );
}
}
add_action( 'pre_get_posts', 'change_slug_struct' );

(this code is from here)

Now after hitting publish, the slug /single-link/ gets deleted, but we always get a 404 when visiting the page. Changing/re-Saving the permalinks did not help. What am I doing wrong?

3 Answers
3

The registering of the custom post type and the permalink modification is OK. The problem is with the WordPress rewrite rules that more than likely will match the “cleaned up” URL of your simple links to pages and it will set the pagename query var not name as your change_slug_struct() function assumed.

So change the function to this to account for all cases:

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'], "https://wordpress.stackexchange.com/" ) ) {
        $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' );

Leave a Comment