为什么“在循环外调模板标签”会出事

作者: admin 分类: wordpress主题制作教程 发布时间: 2026-11-06 18:30

先看一段真实的怪代码

caogenbj 的 single.php(文章页)里,有一段我一直没看懂的代码:

<span>作者: <?php while (have_posts()) : the_post(); ?>
                 <?php the_author(); ?>
              <?php endwhile; ?>
    </span>

一个“作者”字段,为什么要套一层 while 循环?直接用 the_author() 不行吗?

后来我想明白了:原作者遇到了“循环外调标签不生效”的问题,于是用循环绕了过去。

为什么循环外调会出事

文章页(single.php)加载的时候,WordPress 已经查到了这篇文章,但还没有把它设成“当前文章”。

也就是说,全局 $post 此时还不是这篇文章。你在这个位置直接调 the_author(),它读的是一个没设置好的 $post,结果可能是空的,或者读到上一篇文章。

原作者的做法是:先跑一遍循环,让 the_post() 把 $post 设置好,再输出作者。所以有了那个看起来多余的 while。

但这写法有代价

这个循环虽然能让作者显示出来,但它有两个问题:

  1. 它消耗了主循环。跑完这个 while,主循环的指针已经到底了。后面再想输出正文,就得靠 WordPress 的“自动倒带”(下一篇会讲),属于“靠容错在跑”。
  2. 标题、分类、时间也都在循环外。它们能显示,是因为这个 while 刚好把 $post 设好了——顺序上“碰巧对了”,但很脆弱。

正确的写法

标准做法是:用一个循环把整块内容包起来,标题、作者、分类、正文全在循环里面。

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

    <h1><?php the_title(); ?></h1>
    <span>作者: <?php the_author(); ?></span>
    <span>分类: <?php the_category(','); ?></span>
    <span>时间: <?php the_time('Y-m-d'); ?></span>
    <div><?php the_content(); ?></div>

<?php endwhile; endif; ?>

这样 $post 在循环里只被设置一次(单篇文章就一条),后面所有标签都读它,不用再套小循环。

我怎么改的

这次重构,我把 caogenbj 的 single.php 改成了上面那种结构:

  • 删掉了“作者”外面那层 while;
  • 删掉了“正文”外面那层重复的 while;
  • 用一个主循环把标题、meta、正文、标签全包起来。

改完之后,代码短了,逻辑也直了:一个页面只跑一个循环,所有标签都在循环里读同一个 $post。

一个判断标准

以后你写模板,看到下面这种情况,基本可以判定“有问题”:

  • 同一个模板里有 两个以上 while ( have_posts() );
  • the_title()、the_content() 出现在任何 while 之外;
  • 为了输出一个字段,单独套了一个循环。

这三种,都是在“跟 $post 的指针较劲”。正确的做法永远是:用一个循环把要读的内容包住。

小结

一句话记住:循环外调模板标签,读的是一个没设置好的 $post;正确做法是用一个循环把整块内容包起来,别用小循环“凑”。

下一篇讲一个更奇怪的现象:一个页面跑两次循环,为什么第二次还能读到文章?

本系列导航

相关文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Powered by 草根站长笔记 © 2015-2026 草根站长笔记 Inc.版权所有,禁止转载