循环是WordPress用于通过主题的模板文件输出帖子的默认机制。 检索的帖子数量取决于阅读设置中定义的每页显示的帖子数量。 在循环中,WordPress将检索要显示在当前页面上的每个帖子,并根据您的主题说明进行格式化。
循环从WordPress数据库中提取每个帖子的数据,并插入适当的信息代替每个模板标签。 将为每个帖子处理循环中的任何HTML或PHP代码。
简单来说,循环是它的名字:它循环遍历当前页面检索到的每个帖子一次,并执行您的主题中指定的操作。
您可以使用循环来执行多种不同的操作,例如:
- 在您的博客主页上显示帖子标题和摘录;
- 在单个帖子上显示内容和评论;
- 使用模板标签在单个页面上显示内容; 和
- 显示来自Custom Post Types和Custom Fields的数据。
- 您可以在模板文件中自定义循环,以显示和操作不同的内容。
循环详情
基本循环是:
1 2 3 4 5 6 |
<span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); <span class="hljs-meta">?></span></span> ... Display post content <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endwhile</span>; <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endif</span>; <span class="hljs-meta">?></span></span> |
这个循环说,当有帖子时,循环并显示帖子。 详细介绍:
have_posts()函数检查是否有任何帖子。
如果有帖子,只要括号中的条件在逻辑上为真,则while循环将继续执行。 只要have_posts()继续为true,循环将继续。
使用循环
循环应放在index.php中,以及用于显示帖子信息的任何其他模板中。 因为你不想一遍又一遍地复制你的头,循环应该总是在调用get_header()之后放置。 例如:
1 2 3 4 5 |
<span class="php"><span class="hljs-meta"><?php</span> get_header(); <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); <span class="hljs-meta">?></span></span> ... Display post content <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">endif</span>; <span class="hljs-meta">?></span></span> |
在上面的例子中,循环的结尾显示为一个结尾和endif。 循环必须始终以相同的if和while语句开始,如上所述,并且必须以相同的结束语句结尾。
您要应用于所有帖子的任何模板标签必须存在于开始和结束语句之间。
提示:如果没有符合指定条件的帖子可用,您可以添加自定义的404“未找到”消息。 消息必须放在endwhile和endif语句之间,如下面的示例所示。
一个非常简单的index.php文件将如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="php"><span class="hljs-meta"><?php</span> get_header(); <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); the_content(); <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">else</span> : _e( <span class="hljs-string">'Sorry, no posts matched your criteria.'</span>, <span class="hljs-string">'textdomain'</span> ); <span class="hljs-keyword">endif</span>; get_sidebar(); get_footer(); <span class="hljs-meta">?></span></span> |
循环可以显示
循环可以为每个帖子显示多个不同的元素。 例如,许多主题中使用的常见模板标签是:
- next_post_link() – 在这篇文章后按时间顺序发布的一篇链接
- previous_post_link() – 在这篇文章之前根据时间顺序发布了一篇链接
- the_category() – 与正在查看的帖子或页面相关联的类别或类别
- the_author() – 作者的帖子或页面
- the_content() – 页面的主要内容
- the_excerpt() – 一个帖子的主要内容的前55个字,后跟一个省略号(…)或阅读更多链接到完整的帖子。 您还可以使用帖子的“摘录”字段来自定义特定摘录的长度。
- the_ID() – 帖子或页面的ID
- the_meta() – 与帖子或页面关联的自定义字段
- the_shortlink() – 使用网站的网址和帖子或页面的ID链接到页面或帖子
- the_tags() –与帖子相关联的标签或标签
- the_title() – 帖子或页面的标题
- the_time() – 帖子或页面的时间或日期。 这可以使用标准php日期功能格式化来定制。
您还可以使用条件标签,例如:
- is_home() – 如果当前页面是主页,则返回true
- is_admin() – 如果是管理员,返回true,否则返回false
- is_single() – 如果页面当前显示单个帖子,则返回true
- is_page() – 如果页面当前显示单个页面,则返回true
- is_page_template() – 可用于确定页面是否正在使用特定的模板,例如:is_page_template(’about-page.php’)
- is_category() – 如果页面或帖子具有指定的类别,则返回true,例如:is_category(’news’)
- is_tag() – 如果页面或帖子具有指定的标签,则返回true
- is_author() – 如果在作者的归档页面内返回true
- is_search() – 如果当前页面是搜索结果页面,则返回true
- is_404() – 如果当前页不存在,则返回true
- has_excerpt() – 如果帖子或页面有摘录,则返回true
示例
让我们来看一下循环中的一些例子:
基本例子
博客归档
大多数博客都有一个博客归档页面,可以显示一些内容,包括帖子标题,缩略图和摘录。 下面的示例显示了一个简单的循环,检查是否有任何帖子,如果有的话,输出每个帖子的标题,缩略图和摘录。 如果没有帖子,它会以括号显示消息。
1 2 3 4 5 6 7 8 9 |
<span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); <span class="hljs-meta">?></span></span> <span class="hljs-tag"><<span class="hljs-name">h2</span>></span><span class="php"><span class="hljs-meta"><?php</span> the_title(); <span class="hljs-meta">?></span></span><span class="hljs-tag"></<span class="hljs-name">h2</span>></span> <span class="php"><span class="hljs-meta"><?php</span> the_post_thumbnail(); <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> the_excerpt(); <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">else</span>: <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> _e( <span class="hljs-string">'Sorry, no posts matched your criteria.'</span>, <span class="hljs-string">'textdomain'</span> ); <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endif</span>; <span class="hljs-meta">?></span></span> |
个人帖子
在WordPress中,每个帖子都有自己的页面,显示该帖子的相关信息。 模板标签允许您自定义要显示的信息。
在下面的例子中,循环输出帖子的标题和内容。 您可以在帖子或页面模板文件中使用此示例来显示有关该帖子的最基本信息。 您还可以自定义此模板以向帖子添加更多数据,例如类别。
1 2 3 4 5 6 7 8 |
<span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); <span class="hljs-meta">?></span></span> <span class="hljs-tag"><<span class="hljs-name">h1</span>></span><span class="php"><span class="hljs-meta"><?php</span> the_title(); <span class="hljs-meta">?></span></span><span class="hljs-tag"></<span class="hljs-name">h1</span>></span> <span class="php"><span class="hljs-meta"><?php</span> the_content(); <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">else</span>: <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> _e( <span class="hljs-string">'Sorry, no pages matched your criteria.'</span>, <span class="hljs-string">'textdomain'</span> ); <span class="hljs-meta">?></span></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endif</span>; <span class="hljs-meta">?></span></span> |
中间例子
不同类别的风格帖子
下面的例子有几件事情:
首先,它显示每个帖子的标题,时间,作者,内容和类别,类似于上面的单个帖子示例。
接下来,通过使用in_category()模板标签,可以使类别ID为“3”的帖子的样式不同。
此示例中的代码注释在循环的每个阶段提供了详细信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
// Start the Loop. <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); <span class="hljs-comment">/* * See if the current post is in category 3. * If it is, the div is given the CSS class "post-category-three". * Otherwise, the div is given the CSS class "post". */</span> <span class="hljs-keyword">if</span> ( in_category( <span class="hljs-number">3</span> ) ) : <span class="hljs-meta">?></span></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"post-category-three"</span>></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">else</span> : <span class="hljs-meta">?></span></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"post"</span>></span> <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endif</span>; <span class="hljs-meta">?></span></span> // Display the post's title. <span class="hljs-tag"><<span class="hljs-name">h2</span>></span><span class="php"><span class="hljs-meta"><?php</span> the_title() <span class="hljs-meta">?></span></span><span class="hljs-tag"></<span class="hljs-name">h2</span>></span> // Display a link to other posts by this posts author. <span class="hljs-tag"><<span class="hljs-name">small</span>></span><span class="php"><span class="hljs-meta"><?php</span> _e( <span class="hljs-string">'Posted by '</span>, <span class="hljs-string">'textdomain'</span> ); the_author_posts_link() <span class="hljs-meta">?></span></span><span class="hljs-tag"></<span class="hljs-name">small</span>></span> // Display the post's content in a div. <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"entry"</span>></span> <span class="php"><span class="hljs-meta"><?php</span> the_content() <span class="hljs-meta">?></span></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> // Display a comma separated list of the post's categories. <span class="php"><span class="hljs-meta"><?php</span> _e( <span class="hljs-string">'Posted in '</span>, <span class="hljs-string">'textdomain'</span> ); the_category( <span class="hljs-string">', '</span> ); <span class="hljs-meta">?></span></span> // closes the first div box with the class of "post" or "post-cat-three" <span class="hljs-tag"></<span class="hljs-name">div</span>></span> // Stop the Loop, but allow for a "if not posts" situation <span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">else</span> : <span class="hljs-comment">/* * The very first "if" tested to see if there were any posts to * display. This "else" part tells what do if there weren't any. */</span> _e( <span class="hljs-string">'Sorry, no posts matched your criteria.'</span>, <span class="hljs-string">'textdomain'</span> ); <span class="hljs-comment">// Completely stop the Loop.</span> <span class="hljs-keyword">endif</span>; <span class="hljs-meta">?></span></span> |
删除此部分
注意:此部分需要删除,但存在是因为手册插件中的错误无法正确显示主题框中的下一部分。
多重循环
在某些情况下,您可能需要使用多个循环。 例如,您可能希望在页面顶部的内容列表表中显示帖子的标题,然后在页面上进一步显示内容。 由于查询没有被改变,所以我们需要在第二次循环访问这些信息时,回滚循环。 为此,我们将使用函数rewind_posts()。
使用rewind_posts()
您可以再次使用rewind_posts()循环遍历相同的查询。 如果要在页面上的不同位置显示相同的查询两次,这将非常有用。
以下是正在使用的rewind_posts()的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="hljs-comment">// Start the main loop</span> <span class="hljs-meta"><?php</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); the_title(); <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">endif</span>; <span class="hljs-comment">// Use rewind_posts() to use the query a second time.</span> rewind_posts(); <span class="hljs-comment">// Start a new loop</span> <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); the_content(); <span class="hljs-keyword">endwhile</span>; <span class="hljs-meta">?></span> |
创建辅助查询和循环
使用具有相同查询的两个循环相对容易,但并不总是您需要的。 相反,您通常会创建一个辅助查询来在模板上显示不同的内容。 例如,您可能希望在同一页面上显示两组帖子,但对每个组执行不同的操作。 如下所示,一个常见的例子是显示单个帖子,其中包含单个帖子下方相同类别的帖子列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-comment">// The main query.</span> <span class="hljs-keyword">if</span> ( have_posts() ) : <span class="hljs-keyword">while</span> ( have_posts() ) : the_post(); the_title(); the_content(); <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">else</span> : <span class="hljs-comment">// When no posts are found, output this text. </span> _e( <span class="hljs-string">'Sorry, no posts matched your criteria.'</span> ); <span class="hljs-keyword">endif</span>; wp_reset_postdata(); <span class="hljs-comment">/* * The secondary query. Note that you can use any category name here. In our example, * we use "example-category". */</span> $secondary_query = <span class="hljs-keyword">new</span> WP_Query( <span class="hljs-string">'category_name=example-category'</span> ); <span class="hljs-comment">// The second loop. if ( $secondary_query->have_posts() ) </span> <span class="hljs-keyword">echo</span> <span class="hljs-string">'<ul>'</span>; <span class="hljs-keyword">while</span> ( $secondary_query->have_posts() ) : $secondary_query->the_post(); <span class="hljs-keyword">echo</span> <span class="hljs-string">'<li>'</span> . get_the_title() . <span class="hljs-string">'</li>'</span>; <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">echo</span> <span class="hljs-string">'</ul>'</span>; <span class="hljs-keyword">endif</span>; wp_reset_postdata(); <span class="hljs-meta">?></span></span> |
如上例所示,我们首先显示一个常规循环。 然后我们定义一个使用WP_Query查询特定类别的新变量; 在我们的例子中,我们选择了示例类别的插件。
请注意,上述示例中的常规循环有一个区别:它调用wp_reset_postdata()来重置帖子数据。 在您可以使用第二个循环之前,您需要重置帖子数据。 有两种方法可以做到这一点:
- 通过使用rewind_posts()函数; 要么
- 通过创建新的查询对象。
重置多个循环
在您重置它们的模板中使用多个循环时,这很重要。 不这样做可能会导致意外的结果,因为数据在全局$post变量中的存储和使用。 有三种主要的方法来重置循环,具体取决于它们的调用方式。
- wp_reset_postdata()
- wp_reset_query()
- rewind_posts()
使用wp_reset_postdata()
当您使用WP_Query运行自定义或多个循环时,请使用wp_reset_postdata()。 此函数将全局$post变量恢复到主查询中的当前帖子。 如果您遵循最佳做法,这是您将用来重置循环的最常用功能。
要正确使用此功能,请在使用WP_Query的任何循环后放置以下代码:
1 2 |
<span class="php"><span class="hljs-meta"><?php</span> wp_reset_postdata(); <span class="hljs-meta">?></span></span> |
这是一个使用WP_Query的循环的示例,它使用wp_reset_postdata()重置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="php"><span class="hljs-meta"><?php</span> <span class="hljs-comment">// Example argument that defines three posts per page.</span> $args = <span class="hljs-keyword">array</span>( <span class="hljs-string">'posts_per_page'</span> => <span class="hljs-number">3</span> ); <span class="hljs-comment">// Variable to call WP_Query.</span> $the_query = <span class="hljs-keyword">new</span> WP_Query( $args ); <span class="hljs-keyword">if</span> ( $the_query->have_posts() ) : <span class="hljs-comment">// Start the Loop</span> <span class="hljs-keyword">while</span> ( $the_query->have_posts() ) : $the_query->the_post(); the_title(); the_excerpt(); <span class="hljs-comment">// End the Loop</span> <span class="hljs-keyword">endwhile</span>; <span class="hljs-keyword">else</span>: <span class="hljs-comment">// If no posts match this query, output this text.</span> _e( <span class="hljs-string">'Sorry, no posts matched your criteria.'</span>, <span class="hljs-string">'textdomain'</span> ); <span class="hljs-keyword">endif</span>; wp_reset_postdata(); <span class="hljs-meta">?></span></span> |
使用wp_reset_query()
使用wp_reset_query()将WP_Query和全局$post数据恢复到原始主查询。 如果在循环中使用query_posts(),则必须使用此功能来重置循环。 您可以在使用WP_Query自定义循环后使用它,因为它在运行时实际调用wp_reset_postdata()。 然而,最好的做法是使用wp_reset_postdata()与涉及WP_Query的任何自定义循环。
请注意:query_posts()不是最佳实践,如果可能的话应该避免。 因此,您不应该对wp_reset_query()有很多用处。
要正确使用此功能,请在使用query_posts()的任何循环后面放置以下代码。
1 |
<span class="php"><span class="hljs-meta"><?php</span> wp_reset_query(); <span class="hljs-meta">?></span></span> |