You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义文章类型(CPT)分页异常,跳转404页面求助

自定义文章类型(CPT)分页跳转404问题解决方案

问题背景

为portfolio自定义文章类型的列表添加分页功能,此前代码正常运行,现在点击分页链接直接跳转到404页面。后台固定链接设置为自定义结构/blog/%postname%/。

主模板代码

<section id="section-portfolio">
    <div class="container">
        <h1><?php echo get_the_title(); ?></h1>
        <div class="portfolio-wrapper flex">
            <?php
            // grab all Portfolio CPT items
            $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

            $args = array(
                'post_type' => 'portfolio',
                'post_status' => 'publish',
                'posts_per_page' => 4,
                'order'     => 'DESC',
                'paged' => $paged,
            );
            $query = new WP_Query($args);
            if ($query->have_posts()) :
                while ($query->have_posts()) :
                    $query->the_post();
                    // loop through Portfolio ITems
                    // Title
                    if (!empty(get_field('project_name_alt'))) {
                        $projectTitle = get_field('project_name_alt');
                    } elseif (!empty(get_field('short_project_name'))) {
                        $projectTitle = get_field('short_project_name');
                    } else {
                        $projectTitle = get_the_title();
                    }
            ?>
                    <div class="project" style="background-image: url('<?php echo get_field('bg_img'); ?>');">
                        <a href="<?php echo get_the_permalink(); ?>" title="Learn more about the <?php echo get_the_title(); ?> project">
                            <h2 class="title"><?php echo $projectTitle; ?></h2>
                        </a>
                    </div>
            <?php
                endwhile;
                wp_reset_postdata();
            endif;
            ?>
        </div>
        <div class="portfolio-pagination">
            <?php echo get_template_part('template-parts/portfolio-pagination'); ?>
        </div>
    </div>
</section>

分页模板代码

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$data = new WP_Query(array(
    'post_type' => 'portfolio', // your post type name
    'posts_per_page' => 4, // post per page
    'paged' => $paged,
));

if ($data->have_posts()) :
    while ($data->have_posts()) : $data->the_post();

    // Your code
    endwhile;


    $total_pages = $data->max_num_pages;

    if ($total_pages > 1) {

        $current_page = max(1, get_query_var('paged'));

        echo paginate_links(array(
            'base' => get_pagenum_link(1) . '%_%',
            'format' => '/page/%#%',
            'current' => $current_page,
            'total' => $total_pages,
            'prev_text'    => __('« prev'),
            'next_text'    => __('next »'),
        ));
    }
?>
<?php else : ?>
    <h3><?php _e('404 Error&#58; Not Found', ''); ?></h3>
<?php endif; ?>
<?php wp_reset_query(); ?>

CPT注册代码

// PORTFOLIO ITEM
$labels = array(
    'name'                => _x( 'Portfolios', 'Post Type General Name', 'greathouse' ),
    'singular_name'       => _x( 'Portfolio', 'Post Type Singular Name', 'greathouse' ),
    'menu_name'           => __( 'Portfolios', 'greathouse' ),
    'parent_item_colon'   => __( 'Parent Portfolio', 'greathouse' ),
    'all_items'           => __( 'All Portfolios', 'greathouse' ),
    'view_item'           => __( 'View Portfolio', 'greathouse' ),
    'add_new_item'        => __( 'Add New Portfolio', 'greathouse' ),
    'add_new'             => __( 'Add New Portfolio', 'greathouse' ),
    'edit_item'           => __( 'Edit Portfolio', 'greathouse' ),
    'update_item'         => __( 'Update Portfolio', 'greathouse' ),
    'search_items'        => __( 'Search Portfolios', 'greathouse' ),
    'not_found'           => __( 'Not Found', 'greathouse' ),
    'not_found_in_trash'  => __( 'Not found in Trash', 'greathouse' ),
);


$args = array(
    'label'               => __( 'portfolio', 'greathouse' ),
    'description'         => __( 'Portfolios', 'greathouse' ),
    'labels'              => $labels,
    // Features this CPT supports in Post Editor
    'supports'            => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields', 'page-attributes'),
    // You can associate this CPT with a taxonomy or custom taxonomy. 
    'hierarchical'        => false,
    'public'              => true,
    'publicly_queryable' => true,
    'show_ui'             => true,
    'show_in_menu'        => true,
    'show_in_nav_menus'   => true,
    'show_in_admin_bar'   => true,
    'menu_position'       => 5,
    'menu_icon'            => 'dashicons-images-alt',
    'can_export'          => true,
    'has_archive'         => false, // use a cutom page template to display the CPT posts to allow use of PAGE data
    'rewrite' => array('slug' => 'portfolio', 'with_front' => false),
    'exclude_from_search' => false,
    'publicly_queryable'  => true,
    'capability_type'     => 'page',
);

register_post_type( 'portfolio', $args );

问题排查与修复步骤

1. 刷新重写规则

进入后台「设置→固定链接」,直接点击「保存更改」,无需修改任何设置。此操作会强制WordPress重新生成重写规则,解决因CPT注册或固定链接变更导致的规则失效问题。

2. 修正分页链接生成逻辑

当前分页模板中paginate_links的base参数写法错误,会生成不符合重写规则的URL。将分页模板中的该部分替换为:

echo paginate_links(array(
    'base'         => str_replace(999999999, '%#%', esc_url(get_pagenum_link(999999999))),
    'format'       => '/page/%#%',
    'current'      => $current_page,
    'total'        => $total_pages,
    'prev_text'    => __('« prev'),
    'next_text'    => __('next »'),
));

str_replace替换999999999是WordPress官方推荐的写法,能适配各种固定链接结构,避免URL生成错误。

3. 复用主查询对象,避免重复查询

主模板和分页模板分别创建独立的WP_Query实例,既冗余又可能导致分页参数不匹配。修改分页模板,直接引用主模板的查询对象:

<?php
global $query;
if ($query->max_num_pages > 1) {
    $current_page = max(1, get_query_var('paged') ?: get_query_var('page'));
    echo paginate_links(array(
        'base'         => str_replace(999999999, '%#%', esc_url(get_pagenum_link(999999999))),
        'format'       => '/page/%#%',
        'current'      => $current_page,
        'total'        => $query->max_num_pages,
        'prev_text'    => __('« prev'),
        'next_text'    => __('next »'),
    ));
}
?>

同时兼容paged和page参数,解决静态页面模板分页参数识别问题。

4. 检查CPT注册设置

当前has_archive设为false,使用自定义页面模板展示列表是可行的,但如果后续切换到CPT归档页面,需将has_archive改为'portfolio',并再次刷新重写规则。

内容的提问来源于stack exchange,提问作者RRhodes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:44:51