WordPress single.php无法获取当前文章数据问题求助
问题:WordPress单页模板(single.php)无法正确获取当前文章数据及上下篇导航
现象描述
- 基于Twenty Twenty One主题自定义的主题,首页网格展示文章、模态框查看内容功能正常,模态框的上下篇按钮与后台文章排序一致。
- 直接访问文章URL加载single.php时,
the_title()、the_content()返回最早创建的文章内容,而非当前访问的文章; - 通过
get_queried_object_id()获取ID后,用get_the_title($page_id)、get_post_field('post_content', $page_id)能拿到正确内容,但get_next_post()、get_previous_post()仍以最早创建的文章为参考,无法获取正确的上下篇。
single.php代码
<?php /** * The template for displaying all single posts */ $page_id = get_queried_object_id(); get_header(); ?> <span id="page-id" page-ref="<?php echo $page_id; ?>"> </span> <?php get_template_part('template-parts/grid'); ?> </div> <div class="modal-wrapper"> <div id="myModal" class="reveal-modal"> <h1> <?php the_title(); ?> </h1> <?php get_template_part('template-parts/modal'); ?> </div> <div class="reveal-modal-bg"></div> </div> <?php get_footer();
补充:首页grid.php代码
<section class="works"> <div class="cat-menu"> <ul> <a href="<?php echo get_home_url(); ?>"> <li class="js-filter-item">Todos</li> </a> <?php $categories = get_categories(); foreach ($categories as $cat): $category_link = get_category_link($cat->term_id); ?> <a href="<?php echo $category_link; ?>"> <li class="js-filter-item" data-category="<?= $cat->term_id ?>"><?= $cat->name; ?></li> </a> <?php endforeach; ?> </ul> </div> <div class="grid-wrapper"> <div class="js-filter grid"> <?php $args = array( 'post_type' => 'post', 'posts_per_page' => 6 ); $query = new WP_Query($args); if ($query->have_posts()) { // Load posts loop. while ($query->have_posts()) { $query->the_post(); get_template_part('template-parts/content/content', get_theme_mod('display_excerpt_or_full_post', 'excerpt')); } // Previous/next page navigation. } else { // If no content, include the "No posts found" template. get_template_part('template-parts/content/content-none'); } ?> </div> </div> </section>
原因分析
核心问题是自定义查询覆盖了主循环的全局$post变量:
- single.php中调用了
get_template_part('template-parts/grid'),而grid.php里用new WP_Query()创建自定义查询后,执行了$query->the_post()——这个函数会将全局$post变量替换为自定义查询中的帖子(即循环第一篇,也就是最早创建的文章)。 - 自定义循环结束后未重置主循环,导致后续依赖全局
$post的函数(如the_title()、get_next_post())都使用了自定义查询残留的$post值,而非当前单页对应的文章。
解决方案
1. 在grid.php中重置主循环
在grid.php的自定义循环结束后,添加wp_reset_postdata();,恢复全局$post到主查询状态:
<?php $args = array( 'post_type' => 'post', 'posts_per_page' => 6 ); $query = new WP_Query($args); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); get_template_part('template-parts/content/content', get_theme_mod('display_excerpt_or_full_post', 'excerpt')); } // 添加此行重置主循环 wp_reset_postdata(); } else { get_template_part('template-parts/content/content-none'); } ?>
2. (可选)在single.php中手动恢复全局$post
若不想修改grid.php,可在single.php调用grid后,手动将全局$post设置为当前文章:
<?php get_template_part('template-parts/grid'); // 重置全局$post为当前单页文章 global $post; $post = get_post($page_id); setup_postdata($post); ?>
3. 修复上下篇导航的排序逻辑
默认get_next_post()、get_previous_post()按发布日期排序,若后台用了手动排序(依赖menu_order字段),需自定义上下篇查询:
// 获取当前文章的手动排序值 $current_order = get_post_field('menu_order', $page_id); // 获取下一篇:排序值大于当前的最小ID文章 $next_post = get_posts(array( 'post_type' => 'post', 'post_status' => 'publish', 'orderby' => 'menu_order', 'order' => 'ASC', 'numberposts' => 1, 'meta_query' => array( array( 'key' => 'menu_order', 'value' => $current_order, 'compare' => '>' ) ) )); $next_post = !empty($next_post) ? $next_post[0] : false; // 获取上一篇:排序值小于当前的最大ID文章 $prev_post = get_posts(array( 'post_type' => 'post', 'post_status' => 'publish', 'orderby' => 'menu_order', 'order' => 'DESC', 'numberposts' => 1, 'meta_query' => array( array( 'key' => 'menu_order', 'value' => $current_order, 'compare' => '<' ) ) )); $prev_post = !empty($prev_post) ? $prev_post[0] : false;
之后可通过$next_post->post_title、$prev_post->ID等获取上下篇信息。
内容的提问来源于stack exchange,提问作者Pedro F
相关产品推荐
相关产品推荐

