Post

WordPress的主循环

文章目录

内容查询离不开循环,WordPress为内容查询构建了主循环,其中包括常规查询和循环中常用内容的查询函数,还有稍微高级的自定义查询,下面就让我们来一一了解。

主循环简介

在WordPress中显示文章内容都是用主循环(The Loop),包括首页、分类页、文章页和搜索结果等其他页面,自定义查询也是用主循环,这个循环挂载了WordPress许多动作和钩子,通过主循环我们不仅可以快捷有效地把内容展示出来,同时别处的代码(如 functions.php 文件)也能通过动作钩子实现修改查询条件或内容。

最常见的主循环(这样的循环在WordPress模板文件中随处可见,如 index.php):

<span class="pun"><?</span><span class="pln">php</span>
<span class="kwd">if</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span>
<span class="kwd">while</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span><span class="pln"> the_post</span><span class="pun">();</span>
<span class="com">//~ 在这里使用内容函数,如 the_title();</span>
<span class="pln">endwhile</span><span class="pun">;</span>
<span class="pln">endif</span><span class="pun">;</span>
<span class="pun">?></span>

如上代码所示,我们很容易就能看懂其中的原理:WordPress先通过 <span class="pln">have_posts</span><span class="pun">()</span> 判断是否有文章,如果有就使用 while 语句循环,然后在循环中通过 <span class="pln">the_post</span><span class="pun">()</span> 设置当前文章内容的全局变量,这样我们就可以轻而易举地在循环中使用函数输出内容到浏览器了。

如果你想找没有找到内容的时候显示一个提示,你可以这样:

<span class="pun"><?</span><span class="pln">php</span>
<span class="kwd">if</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span>
<span class="kwd">while</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span><span class="pln"> the_post</span><span class="pun">();</span>
<span class="com">//~ 在这里使用内容函数,如 the_title();</span>
<span class="pln">endwhile</span><span class="pun">;</span> <span class="kwd">else</span> <span class="pun">:</span>
<span class="com">//~ 在这里放置关于没有找到内容的提示</span>
<span class="pln">endif</span><span class="pun">;</span>
<span class="pun">?></span>

常用函数

在主循环中最常用到的函数:

  1. 使用 <span class="pln">the_ID</span><span class="pun">()</span> 输出文章ID(返回值使用 <span class="pln">get_the_ID</span><span class="pun">()</span>
  2. 使用 <span class="pln">the_title</span><span class="pun">()</span> 输出文章标题(返回值使用 <span class="pln">get_the_title</span><span class="pun">()</span>
  3. 使用 <span class="pln">the_title_attribute</span><span class="pun">()</span> 输出文章标题属性
  4. 使用 <span class="pln">the_permalink</span><span class="pun">()</span> 输出文章固定链接(返回值使用 <span class="pln">get_permalink</span><span class="pun">()</span>
  5. 使用 <span class="pln">the_shortlink</span><span class="pun">()</span> 输出文章短链接(返回值使用 <span class="pln">wp_get_shortlink</span><span class="pun">()</span>
  6. 使用 <span class="pln">the_excerpt</span><span class="pun">()</span> 输出文章摘要(返回值使用 <span class="pln">get_the_excerpt</span><span class="pun">()</span>
  7. 使用 <span class="pln">the_content</span><span class="pun">()</span> 输出文章内容(返回值使用 <span class="pln">get_the_content</span><span class="pun">()</span>
  8. 使用 <span class="pln">the_category</span><span class="pun">()</span> 输出文章分类目录(返回值使用 <span class="pln">get_the_category</span><span class="pun">()</span> ,返回分类列表使用<span class="pln">get_the_category_list</span><span class="pun">()</span>
  9. 使用 <span class="pln">the_tags</span><span class="pun">()</span> 输出文章标签(返回值使用 <span class="pln">get_the_tags</span><span class="pun">()</span> ,返回标签列表使用<span class="pln">get_the_tag_list</span><span class="pun">()</span>
  10. 使用 <span class="pln">the_meta</span><span class="pun">()</span> 输出文章自定义meta信息
  11. 使用 <span class="pln">the_author</span><span class="pun">()</span> 输出文章作者(返回值使用 <span class="pln">get_the_author</span><span class="pun">()</span>
  12. 使用 <span class="pln">the_author_link</span><span class="pun">()</span> 输出文章作者(带链接)(返回值使用 <span class="pln">get_the_author_link</span><span class="pun">()</span>

更多函数请浏览WordPress官方的函数参考页面。

写一个循环

好了,既然我们知道WordPress主循环是什么样的了,也知道在循环中应该用什么函数输出内容了,下面就让我们来写一个循环来试试身手吧!

首先,我们写一个归档页的(也可以是首页的)模板,归档的就是文章列表了,文章列表一般都是有一个文章标题(带链接可点击)和一段摘要:

<span class="pun"><?</span><span class="pln">php</span>
<span class="com">//~ 载入头部模板</span>
<span class="pln">get_header</span><span class="pun">();</span>
<span class="com">//~ 循环开始</span>
<span class="kwd">if</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span>
<span class="kwd">while</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span><span class="pln"> the_post</span><span class="pun">();</span>
<span class="pun">?></span>

<span class="tag"><h3></span><span class="pln"><a href="</span><span%20class="pun"><?</span><span class="pln">php the_permalink</span><span class="pun">();?></span><span class="pln">" title="</span><span%20class="pun"><?</span><span class="pln">php the_title_attribute</span><span class="pun">();?></span><span class="pln">"></span><span class="pun"><?</span><span class="pln">php the_title</span><span class="pun">();?></span><span class="tag"></a></h3></span>

<span class="tag"><div></span><span class="pun"><?</span><span class="pln">php the_excerpt</span><span class="pun">();?></span><span class="tag"></div></span>

<span class="pun"><?</span><span class="pln">php</span>
<span class="pln">endwhile</span><span class="pun">;</span>
<span class="pln">endif</span><span class="pun">;</span>
<span class="com">//~ 载入侧边栏模板</span>
<span class="pln">get_sidebar</span><span class="pun">();</span>
<span class="com">//~ 载入底部模板</span>
<span class="pln">get_footer</span><span class="pun">();</span>
<span class="pun">?></span>

好了,我们有一个归档页,接下来就应该是具体内容的文章页了,文章页的标题不需要带链接,但应该展示更多关于这篇文章的内容,如作者、分类、标签等,同时文章内容输出的就不应该是摘要了,而是全部内容。

<span class="pun"><?</span><span class="pln">php</span>
<span class="com">//~ 载入头部模板</span>
<span class="pln">get_header</span><span class="pun">();</span>
<span class="com">//~ 循环开始</span>
<span class="kwd">if</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span>
<span class="kwd">while</span> <span class="pun">(</span><span class="pln">have_posts</span><span class="pun">())</span> <span class="pun">:</span><span class="pln"> the_post</span><span class="pun">();</span>
<span class="pun">?></span>

<span class="tag"><h3></span><span class="pun"><?</span><span class="pln">php the_title</span><span class="pun">();?></span><span class="tag"></h3></span>

<span class="tag"><p></span><span class="pln">文章作者:</span><span class="pun"><?</span><span class="pln">php the_author_link</span><span class="pun">();</span> <span class="pun">?></span><span class="tag"></p></span>

<span class="tag"><div</span> <span class="atn">class</span><span class="pun">=</span><span class="atv">"cat"</span><span class="tag">></span><span class="pln">分类:</span><span class="pun"><?</span><span class="pln">php the_category</span><span class="pun">(</span><span class="str">', '</span><span class="pun">);?></span><span class="tag"></div></span>

<span class="pun"><?</span><span class="pln">php the_tags</span><span class="pun">(</span><span class="str">'<div class="tag">标签:'</span><span class="pun">,</span> <span class="str">', '</span><span class="pun">,</span> <span class="str">'</div>'</span> <span class="pun">);</span> <span class="pun">?></span>

<span class="tag"><div></span><span class="pun"><?</span><span class="pln">php the_content</span><span class="pun">();?></span><span class="tag"></div></span>

<span class="pun"><?</span><span class="pln">php</span>
<span class="pln">endwhile</span><span class="pun">;</span>
<span class="pln">endif</span><span class="pun">;</span>
<span class="com">//~ 载入侧边栏模板</span>
<span class="pln">get_sidebar</span><span class="pun">();</span>
<span class="com">//~ 载入底部模板</span>
<span class="pln">get_footer</span><span class="pun">();</span>
<span class="pun">?></span>

细心的童鞋应该有了新的发现,没错,就是 <span class="pln">the_category</span><span class="pun">()</span><span class="pln">the_tags</span><span class="pun">()</span> 有传入参数;其中 <span class="pln">the_category</span><span class="pun">()</span> 传入的是一个逗号,显然这是多个分类时的分隔符;而 <span class="pln">the_tags</span><span class="pun">()</span> 则传入了三个参数,中间那个逗号显然也是分隔符,而前后两个参数则是添加在标签内容前后的内容;这些函数的具体用法和传入参数都可以在WordPress官方的函数参考中找到。

自定义循环

WordPress常规循环我们都已经了解,包括归档页和文章页(其实无论什么页面,循环都一样,只是循环里显示的内容略有区别而已),接下来,我们来学习稍微高级一点的自定义查询循环。

在WordPress中自定义查询内容我们可以使用 <span class="pln">WP_Query</span> 类,不过,还有比这更简单的方法,那就是使用 <span class="pln">query_posts</span><span class="pun">()</span> 函数,这个函数是来自 <span class="pln">WP_Query</span> 类的封装,所以传入参数完全一样(传入参数官方说明),但用法更简单,代码更简洁。

<span class="pun"><?</span><span class="pln">php</span>
<span class="com">//~ 通过 $args 传入查询参数,可以是数组,也可以是文本模式(以key=value格式并以&隔开多个参数)</span>
<span class="pln">query_posts</span><span class="pun">(</span><span class="pln"> $args </span><span class="pun">);</span>

<span class="com">//~ 循环</span>
<span class="kwd">while</span> <span class="pun">(</span><span class="pln"> have_posts</span><span class="pun">()</span> <span class="pun">)</span> <span class="pun">:</span><span class="pln"> the_post</span><span class="pun">();</span>
<span class="com">//~ 在这里使用内容函数,如 the_title();</span>
<span class="pln">endwhile</span><span class="pun">;</span>

<span class="com">//~ 循环后使用这个函数重置查询,以防影响其他常规查询</span>
<span class="pln">wp_reset_query</span><span class="pun">();</span>
<span class="pun">?></span>

以下是一个例子(查询最新5篇文章):

<span class="pun"><?</span><span class="pln">php</span>
<span class="pln">query_posts</span><span class="pun">(</span> <span class="str">'orderby=date&order=DESC&posts_per_page=5'</span> <span class="pun">);</span>

如果要把自定义参数和当前页面预置的查询参数合并起来,你可以这样:

<span class="pun"><?</span><span class="pln">php</span>
<span class="com">//~ 在预置查询条件的前提下把排序改为升序</span>
<span class="kwd">global</span><span class="pln"> $query_string</span><span class="pun">;</span>
<span class="pln">query_posts</span><span class="pun">(</span><span class="pln"> $query_string </span><span class="pun">.</span> <span class="str">'&order=ASC'</span> <span class="pun">);</span>

改变预置参数

通过 <span class="pln">query_posts</span><span class="pun">()</span> 函数我们可以自定义查询条件(一般用来新建自定义查询而不是直接使用在常规查询中),但是有些时候,我们需要更改常规查询的查询条件,如在首页排除某个分类,或者是在搜索结果中排除页面。

对于这样的需求,建议通过 pre_get_posts 动作来实现,如在首页排除ID是1和4的分类,我们只需这样:

<span class="kwd">function</span><span class="pln"> exclude_category</span><span class="pun">(</span><span class="pln"> $query </span><span class="pun">)</span> <span class="pun">{</span>
<span class="kwd">if</span> <span class="pun">(</span><span class="pln"> $query</span><span class="pun">-></span><span class="pln">is_home</span><span class="pun">()</span> <span class="pun">&&</span><span class="pln"> $query</span><span class="pun">-></span><span class="pln">is_main_query</span><span class="pun">()</span> <span class="pun">)</span><span class="pln"> $query</span><span class="pun">-></span><span class="kwd">set</span><span class="pun">(</span> <span class="str">'cat'</span><span class="pun">,</span> <span class="str">'-1,-4'</span> <span class="pun">);</span>
<span class="pun">}</span>
<span class="pln">add_action</span><span class="pun">(</span> <span class="str">'pre_get_posts'</span><span class="pun">,</span> <span class="str">'exclude_category'</span> <span class="pun">);</span>

在搜索结果中只显示文章的结果,我们可以这样:

<span class="kwd">function</span><span class="pln"> search_filter</span><span class="pun">(</span><span class="pln">$query</span><span class="pun">)</span> <span class="pun">{</span>
<span class="kwd">if</span> <span class="pun">(</span> <span class="pun">!</span><span class="pln">is_admin</span><span class="pun">()</span> <span class="pun">&&</span><span class="pln"> $query</span><span class="pun">-></span><span class="pln">is_main_query</span><span class="pun">()</span> <span class="pun">&&</span><span class="pln"> $query</span><span class="pun">-></span><span class="pln">is_search </span><span class="pun">)</span><span class="pln"> $query</span><span class="pun">-></span><span class="kwd">set</span><span class="pun">(</span><span class="str">'post_type'</span><span class="pun">,</span><span class="pln"> array</span><span class="pun">(</span> <span class="str">'post'</span> <span class="pun">)</span> <span class="pun">);</span>
<span class="pun">}</span>
<span class="pln">add_action</span><span class="pun">(</span><span class="str">'pre_get_posts'</span><span class="pun">,</span><span class="str">'search_filter'</span><span class="pun">);</span>

以上只是两个简单的例子,更多用法可以参考WordPress官方文档关于 pre_get_posts 动作的说明

Leave a Reply