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

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变量:

  1. single.php中调用了get_template_part('template-parts/grid'),而grid.php里用new WP_Query()创建自定义查询后,执行了$query->the_post()——这个函数会将全局$post变量替换为自定义查询中的帖子(即循环第一篇,也就是最早创建的文章)。
  2. 自定义循环结束后未重置主循环,导致后续依赖全局$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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:38:08