自定义文章类型(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: 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
相关产品推荐
相关产品推荐

