如何讓 WordPress Custom Post Type 不要有 slug 前綴?

因為我們是使用 ACF,所以要透過 add_filter 來攔截註冊 post type 的設定


add_filter('register_post_type_args', function($args, $post_type) {
    // Target your specific post type registered by ACF
    if ($post_type === 'seo-single-post') {
        $args['rewrite'] = array('slug' => '', 'with_front' => false); // Remove slug prefix
    }
    return $args;
}, 10, 2);

add_action('init', function() {
    add_rewrite_rule(
        '^([^/]+)?$',
        'index.php?seo-single-post=$matches[1]',
        'top'
    );
});

add_action('template_redirect', function() {
    // Get the current post type
    global $wp_query;

    if (is_singular('seo-single-post')) {
        $current_url = $_SERVER['REQUEST_URI'];

        // Check if the URL contains the slug
        if (strpos($current_url, '/seo-single-post/') !== false) {
            // Redirect to the URL without the slug (301 Permanent Redirect)
            wp_redirect(home_url(str_replace('/seo-single-post/', '/', $current_url)), 301);
            exit;
        }
    }
});

add_filter('post_type_link', function($post_link, $post, $leavename) {
    // Check if it's your custom post type
    if ($post->post_type === 'seo-single-post') {
        // Generate the permalink without the slug
        $post_link = home_url($leavename ? '/%postname%/' : '/' . $post->post_name . '/');
    }
    return $post_link;
}, 10, 3);

add_action('pre_get_posts', function($query) {
    // Check if it's the main query and not in admin
    if (!is_admin() && $query->is_main_query() && isset($query->query_vars['seo-single-post'])) {
        $slug = $query->query_vars['seo-single-post'];

        // Try to find a post in the custom post type with the slug
        $post = get_posts(array(
            'name'        => $slug,
            'post_type'   => 'seo-single-post',
            'post_status' => 'publish',
            'numberposts' => 1,
        ));

        // If no post is found, treat it as a page
        if (empty($post)) {
            $query->set('post_type', 'page');
            $query->set('name', $slug); // Ensure the query uses the slug for the page
            unset($query->query_vars['seo-single-post']); // Remove the custom post type query var
        }
    }
});