循环是 WordPress 通过主题模板文件输出文章的默认机制 。在循环中,WordPress 遍历当前页面获取到的所有文章,然后使用主题中的模版标签将其格式化并输出。

我们可以用 WordPress 循环来做很多事情,例如:

  • 在网站首页显示多个文章模块
  • 在文章详情页面显示内容和评论
  • 在侧边栏中显示最新文章或热门文章
  • 显示指定文章类型或分类方法中的数据
  • 根据指定的条件获取数据并显示在文章模块中

循环细节

循环的基本使用方法如下。

复制<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); // 显示文章内容 endwhile; endif; ?>

上面的代码首先判断是否有循环,如果有,则逐个显示循环中的内容。

  • have_posts() 函数检查当前页面是否有文章。
  • 只要括号中的条件逻辑为真,while 循环就会继一直执行下去。

使用文章循环

循环应放在index.php或其他用来显示文章的模板中。因为我们不想在每个文章中都显示网站页头,所以循环代码应该放在[get_header()](https://developer.wordpress.org/reference/functions/get_header/) 之后。

复制`<?php get_header();

// 循环代码从这里开始 if ( have_posts() ) : while ( have_posts() ) : the_post(); // 显示文章内容 endwhile; endif; ?>`

如以上代码所示,循环必须以ifwhile 语句开头,以endwhileendif 语句结束。用以显示文章内容的模版标签必须在循环开始语句和结束语句中间。

如果当前页面没有文章,我们可以显示一个 404 错误信息,这个信息必须放在endwhileendif 语句之间 ,如下所示。

这是一个非常简单的index.php 文章。

复制`<?php get_header();

if ( have_posts() ) : while ( have_posts() ) : the_post(); the_content(); endwhile; else : _e( ‘抱歉,未找到您需要的文章。’, ‘textdomain’ ); endif;

get_sidebar(); get_footer(); ?>`

可以在文章循环中显示什么

我们可以在循环中使用模版标签显示各种文章内容、文章自定义字段,下面是一些常用的模版标签:

  • [next_post_link()](https://developer.wordpress.org/reference/functions/next_post_link/):显示在当前文章之后发布的文章的链接
  • [previous_post_link()](https://developer.wordpress.org/reference/functions/previous_post_link/)– 显示在当前文章之前发布的文章的链接
  • [the_category()](https://developer.wordpress.org/reference/functions/the_category/):显示当前文章所在的分类
  • [the_author()](https://developer.wordpress.org/reference/functions/the_author/):显示文章作者
  • [the_content()](https://developer.wordpress.org/reference/functions/the_content/):显示文章正文内容
  • [the_excerpt()](https://developer.wordpress.org/reference/functions/the_excerpt/):显示文章摘要
  • [the_ID()](https://developer.wordpress.org/reference/functions/the_id/):显示文章或页面 ID
  • [the_meta()](https://developer.wordpress.org/reference/functions/the_meta/):显示文章或页面的自定义字段
  • [the_shortlink()](https://developer.wordpress.org/reference/functions/the_shortlink/):显示文章的短链接
  • [the_tags()](https://developer.wordpress.org/reference/functions/the_tags/):显示文章所包含的标签
  • [the_title()](https://developer.wordpress.org/reference/functions/the_title/):显示文章标题
  • [the_time()](https://developer.wordpress.org/reference/functions/the_time/):显示文章发布时间

显示文章的时候,我们可以使用条件标签控制文章是否在满足某种条件的情况下显示。

示例

下面让我们看一些 WordPress 循环的真实使用示例。

基本示例

文章列表页

大多数网站都有文章列表页面,在列表页面中,我们可以显示这个列表中所有文章的标题、缩略图、摘要、分类等信息。下面的示例是一个简单的列表页面,示例代码首先检查是否有文章,如果有,显示文章标题、缩略图、摘要,如果没有,则显示提示消息。

复制<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); the_title( '<h2>', '</h2>' ); the_post_thumbnail(); the_excerpt(); endwhile; else: _e( '抱歉,未找到您需要的文章。', 'textdomain' ); endif; ?>

文章详情页

在 WordPress 中,每个文章都有自己的详情页面,我们可以使用模版标签在这个页面上显示文章的各种信息。

在下面的示例中,模版循环显示了文章的标题和内容,除此之外,我们还可以显示文章正文、文章作者、发表时间等信息。

复制<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); the_title( '<h1>', '</h1>' ); the_content(); endwhile; else: _e( '抱歉,未找到您需要的文章。', 'textdomain' ); endif; ?>

为某个分类中的文章显示不同的内容和样式

我们来看一下模版示例,在这个示例中:

  • 首先,显示每篇文章的标题、发布时间、作者、正文和分类。
  • 然后,我们利用判断函数in_category() 来为分类 ID 为 3 的文章显示不同的样式。

复制`<?php // 开始循环 if ( have_posts() ) : while ( have_posts() ) : the_post(); // 判断文章是否在分类 3 中,如果是,添加 CSS 类 “post-category-three”. 否则,添加 CSS 类 “post”. if ( in_category( 3 ) ) : ?>

<?php else : ?>
<?php endif;

  1. // 显示文章标题
  2. the_title( '<h2>', ';</h2>' );
  3. // 显示该文章作者存档的链接
  4. printf( __( '作者 %s', 'textdomain' ), get_the_author_posts_link() );
  5. // 显示文章内容
  6. ?>
  7. <div>
  8. <?php the_content() ?>
  9. </div>
  10. <?php
  11. // 显示逗号分隔的文章分类
  12. _e( '文章分类 ', 'textdomain' ); the_category( ', ' );
  13. // 关闭 div
  14. ?>
  15. </div>
  16. <?php
  17. // 结束循环,下面是没有文章时显示的内容
  18. endwhile;

else : // 如果没有文章,显示提示消息 _e( ‘抱歉,未找到您需要的文章。’, ‘textdomain’ );

// 结束判断和循环 endif; ?>`

主循环

主循环是 WordPress 中的一个非常重要的概念,在开始学习多个循环之前,我们首先需要了解一下什么是主循环。

当我们访问 WordPress 站点的时候,WordPress 会根据我们访问的页面为我们新建一个文章查询和循环,设置一个 $wp_query 全局变量。这个变量就是主循环数据的变量,我们可以直接在页面模版中循环这个数据来输出文章。

看一下下面的代码:

复制if ( have_posts() ) : while ( have_posts() ) : the_post(); the_title(); endwhile; endif;

为了说明主循环,我们稍微改写一下代码。

复制if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); the_title(); endwhile; endif;

两段代码是等效的,为了保持代码的简洁性,WordPress 隐藏了全局的主循环变量$wp_query

多个循环

在某些情况下,我们可能需要使用多个循环。例如,我们可能需要在页面顶部的内容列表中显示文章标题,然后在页面下方显示文章内容。因为我们使用的是同一个循环,我们只需要在开始第二次循环之前重置循环即可,使用函数rewind_posts() 即可实现这个功能。

使用rewind_posts() 函数重新开始循环

我们可以使用 rewind_post() 函数让循环从循环中的第一个元素重新开始,当我们需要在一个页面中循环同一个查询时,这个函数非常有用。

这下面是一个rewind_posts() 示例 :

复制`<?php // 开始第一次循环 if ( have_posts() ) : while ( have_posts() ) : the_post(); the_title(); endwhile; endif;

// 使用 rewind_posts() 重置循环 rewind_posts();

// 开始第二次循环 while ( have_posts() ) : the_post(); the_content(); endwhile; ?>`

新建查询和文章循环

如上面的代码所示,我们可以非常容易的循环同一个查询结果两次或多次,但是很多时候,这不是我们所需要的。有时候我们需要在一个页面上显示不同的文章,例如,我们需要在页面的左侧显示所有文章,右侧显示分类「example-category」中的文章。这种情况下,我们需要新建一个文章查询,然后循环这个新的文章查询结果,示例代码如下:

复制`<?php // 显示所有文章 if ( have_posts() ) : while ( have_posts() ) : the_post(); the_title(); the_content(); endwhile; else : _e( ‘抱歉,未找到您需要的文章。’ ); endif; wp_reset_postdata();

// 创建一个新的文章查询,获取分类 「category_name」中的文章。 $secondary_query = new WP_Query( ‘category_name=example-category’ );

// 循环新的查询结果 if ( $secondary_query->have_posts() ) echo ‘

    ‘; while ( $secondary_query->have_posts() ) : $secondary_query->the_post(); the_title( ‘
  • ‘, ‘
  • ‘ ); endwhile; echo ‘
‘; endif; wp_reset_postdata(); ?>`

如上例所示,我们首先显示主循环中的结果。然后,使用WP_Query 类查询指定分类中的文章。

请注意,上面示例中的第二个循环和主循环还有一个区别:后者调用了 wp_reset_postdata() 函数来重置文章数据。

重置多个文章循环

在循环中,文章数据是存储在$post全局变量中的,在循环结束时,我们需要重置这个全局变量,否则会导致一些难以调试的 Bug 。根据循环调用的方式,有三个函数可以用来重置循环。

  • [wp_reset_postdata()](https://developer.wordpress.org/reference/functions/wp_reset_postdata/)
  • [wp_reset_query()](https://developer.wordpress.org/reference/functions/wp_reset_query/)
  • [rewind_posts()](https://developer.wordpress.org/reference/functions/rewind_posts/)

使用wp_reset_postdata() 重置文章数据

使用 WP_Query 新建自定义循环或使用了多个循环时,请使用 wp_reset_postdata() 来重置文章数据,这个函数将全局变量 $post 变量还原到主查询中的当前帖子。如果我们在进行 WordPress开发时遵循了最佳实践,该函数是用来重置循环的最常见函数。

建议在使用了 WP_Query 类新建了查询和循环时,都要使用 wp_reset_postdata() 函数重置文章数据。

下面是使用 WP-Query 类新建了查询和循环后,使用 wp_reset_postdata() 还原文章数据的示例代码。

复制 `<?php // WP_Query 所使用的参数 $args = array( ‘posts_per_page’ => 3 );

// 调用 WP_Query 新建文章查询. $the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) : // 开始循环 while ( $the_query->have_posts() ) : $the_query->the_post(); the_title(); the_excerpt(); // 结束循环 endwhile; else: _e( ‘抱歉,未找到您需要的文章。’, ‘textdomain’ ); endif;

wp_reset_postdata(); ?>`

使用wp_reset_query() 重置主循环和文章数据

因为query_posts() 函数新建的循环是一个主循环,在使用了这个函数新建查询后,我们必须使用wp_reset_query() 来还原查询和文章数据。如果使用了WP_Query 新建查询,我们可以使用 wp_reset_query() 函数来还原文章数据(因为该函数已经调用了 wp_reset_postdata() 函数),但是最好的做法是使用 wp_reset_postadata 函数来还原使用 WP_Query 新建的文章循环。

因为query_posts()会新建一个主循环来替代当前页面的主循环,使用这个函数会带来一些副作用,新建循环是,我们尽量使用 WP_Query 按不是 query_posts 函数。