本文目录
[隐藏]
- 1描述
- 2注意事项
- 2.1改变主循环(Alters Main Loop)
- 2.2二级循环(Secondary Loops)
- 2.3分页(Pagination)
- 2.4额外的SQL查询
- 3用法
- 3.1保留现有的查询参数
- 3.2结合参数
- 4参数
- 5例子
- 5.1在首页排除分类
- 5.2检索某一篇文章
- 5.3一个分类的所有文章
- 5.4聚合 Feeds
- 5.5传递变量到 query_posts
- 5.5.1例 1
- 5.5.2例 2
- 5.5.3例 3
- 5.5.4例 4
- 5.5.5例 5
- 6所在文件
- 7其他资源
- 8相关函数
描述
query_posts() 可以用来控制在循环(Loop)中显示哪些文章。它可以替换主查询,而使用一个新的查询来获取文章。要清除 query_posts() 的新查询,可以使用 wp_reset_query() 来重置查询。
我们强烈建议您使用 pre_get_posts 来替代 query_posts() ,同时使用 is_main_query 来检查主查询。
举个例子,在首页(homepage),你可以看到最新的10篇文章。如果你想仅仅显示 5 篇文章(不在乎分页),你可以像这样使用 query_posts() :
1 |
query_posts( 'posts_per_page=5' ); |
下面是在 functions.php 中使用 pre_get_posts 实现类型的结果:
1 2 3 4 5 6 |
function five_posts_on_homepage( $query ) { if ( $query->is_home() && $query->is_main_query() ) { $query->set( 'posts_per_page', '5' ); } } add_action( 'pre_get_posts', 'five_posts_on_homepage' ); |
注:pre_get_posts 动作无法正常工作于 页面(Page) 查询。
注意事项
query_posts() 只是一种查询数据库获取文章列表的方法。在使用 query_posts() 之前,你需要了解它的弊端。
改变主循环(Alters Main Loop)
query_posts() 是通过替换查询条件来改变主循环生成的内容的。一旦你使用 query_posts(), 你文章的相关的全局变量和模板标签都将改变。条件标签(Conditional tags)在你调用 query_posts() 之后也会发生改变——这可能是也可能不是预期的结果。
二级循环(Secondary Loops)
要创建 二级列表(例如:在页面底部显示相关文章列表,或者在边栏小工具中显示一个列表), 尝试使用 WP_Query 或 get_posts() 来获取文章。
如果你一定要用 query_posts() ,请确保你在上一个使用了 query_posts() 的循环结束的地方,使用 wp_reset_query() 来重置查询。
分页(Pagination)
分页将无法正常工作,除非你适当设置 ‘paged’ 查询: adding the paged parameter
额外的SQL查询
如果你在模板页面中使用 query_posts ,WordPress 就会在 query_posts 时执行数据库查询和检索记录(即它是如何知道是服务于哪个模板页面!)所以,当你使用 query_posts() 覆盖了默认的查询,你基本上就扔掉了默认的查询以及它的结果,并重新对数据库执行了另一个查询。
这也许不是一个问题,尤其是如果你正在处理一个较小的基于博客的网站。但是对于大型网站、大型数据库以及较高的访客流量来说,你就要考虑使用其他查询方式来减少 SQL查询了,比如直接修改默认的查询(在它被请求前)。使用请求(request)过滤器可是实现这点。
‘parse_query’ 和 ‘pre_get_posts’ 过滤器也可用来修改内部用于生成SQL查询数据库的 $query 对象。
用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php // 查询 query_posts( $args ); // 循环 while ( have_posts() ) : the_post(); echo '<li>'; the_title(); echo '</li>'; endwhile; // 重置查询 wp_reset_query(); ?> |
在模板文件的循环前面添加 query_posts() ,wp_query 对象将根据你给定的参数生成一个新的 SQL 查询。当你这样做时,WordPress 将忽视通过URL检索到的其他参数(例如 页码或分类)。
保留现有的查询参数
如果你想保留原来的查询参数作为当前查询的一部分,然后添加或重写一些参数,你可以在 query_posts() 中使用全局变量 $query_string 。
例如,要修改文章的显示顺序并且不影响接下来的查询,你可以在循环(The Loop)前面使用下面的代码:
1 2 |
global $query_string; query_posts( $query_string . '&order=ASC' ); |
当你通过这种方式使用 query_posts() , 参数的前面必须添加一个 & 。或者你可以合并原来的查询数组到到你的参数数组:
1 2 3 |
global $wp_query; $args = array_merge( $wp_query->query_vars, array( 'post_type' => 'product' ) ); query_posts( $args ); |
结合参数
从上面的例子中,你可能已经注意到,你可以使用 & 来结合参数:
1 |
query_posts( 'cat=3&year=2004' ); |
在首页查询当前月份的分类ID为 13 的文章:
1 2 3 |
if ( is_home() ) { query_posts( $query_string . '&cat=13&monthnum=' . date( 'n', current_time( 'timestamp' ) ) ); } |
下面的例子,将返回一组文章(分类ID为 1 和 3 、显示 2 篇文章、根据标题降序排列):
1 |
query_posts( array( 'category__and' => array(1,3), 'posts_per_page' => 2, 'orderby' => 'title', 'order' => 'DESC' ) ); |
下面的例子将返回分类ID为 1 和 标签为 “apples”的文章:
1 |
query_posts( 'cat=1&tag=apples' ); |
你可以使用加号 + 来添加更多标签:
1 |
query_posts( 'cat=1&tag=apples+apples' ); |
参数
参数详情请阅读 Parameter section of the WP_Query class article.
下面的例子同样可以用于 WP_Query 对象。
例子
在首页排除分类
将下面的代码添加到 index.php 文件,这样首页将显示 除了分类ID为 3 以外的其他所有文章:
1 2 3 4 5 |
<?php if ( is_home() ) { query_posts( 'cat=-3' ); } ?> |
你还可以以此类推添加更多要排除的分类:
1 2 3 4 5 |
<?php if ( is_home() ) { query_posts( 'cat=-1,-2,-3' ); } ?> |
检索某一篇文章
要检索某一篇文章,可以使用下面的代码:
1 |
query_posts( 'p=5' ); |
注:如果检索的是一个附件,那你应该使用 attachment_id 代替 p :
1 |
query_posts( 'attachment_id=5' ); |
如果你想使用“阅读更多(Read More)”功能,你就需要在查询中设置全局变量 $more 的值为 0 :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php // 检索 ID 为 5 的文章 query_posts( 'p=5' ); // 设置 $more 为 0 以便仅仅获取文章的第一部分 global $more; $more = 0; // 循环 while (have_posts()) : the_post(); the_content( '阅读全文 »' ); endwhile; ?> |
一个分类的所有文章
在 设置 > 阅读 中,“博客页面最多显示”的设置可以影响你的结果。为了克服这个问题,你可以添加 ‘posts_per_page’ 参数,例如:
1 |
query_posts( array ( 'category_name' => 'my-category-slug', 'posts_per_page' => -1 ) ); |
这样将显示这个分类的所有文章。
但是,对于子分类(subcategories or child categories), ‘The Category Name’ 可能就没办法生效,请使用 ‘category-slug’ 替代。阅读 Function_Reference/is_category。
1 2 3 4 5 |
if (is_category('category-slug')): query_posts(array('category_name' => 'my-category-slug', 'posts_per_page' => -1 )); endif; |
聚合 Feeds
在 设置 > 阅读 中,“Feed 中显示最近”的设置 或者 ‘posts_per_rss’ 参数将在 Feed 中覆盖任何查询的 ‘posts_per_page’ 参数。
为了克服这个问题(例如在自定义的 ics Feed 中,输出所有符合条件的文章),可以使用 “posts_limit” 过滤器:
1 2 3 4 |
if ( isset ( $query->query_vars['feed'] ) and ( $query->query_vars['feed'] == 'ics' ) ) { add_filter( 'post_limits', '__return_empty' ); } |
传递变量到 query_posts
有两种方法可以传递一个变量到查询中,你可以根据自己的需求选择。就像其他例子一样,将下面的代码添加到循环的上面:
例 1
在这个例子中,我们在查询运行前串连查询条件。首先分配变量,然后串连,然后运行它。在这里,我们从其他地方拉来一个分类变量:
1 2 3 4 5 6 7 8 |
// 分配参数作为当前分类 $categoryvariable = $cat; // 串连查询 $args = 'cat=' . $categoryvariable . '&orderby=date&order=ASC'; // 运行查询 query_posts( $args ); |
例 2
在这个例子中,双引号是告诉 PHP 这是一个闭合。对于这个例子,我们获取当前 月份 和 年份,然后告诉 query_posts() 显示当前 年/月 的文章。此外,我们使用升序排列(ASE) ,这样,最老的文章将显示在页面的顶部:
1 2 3 4 |
$current_year = date('Y'); $current_month = date('m'); query_posts( "cat=22&year=$current_year&monthnum=$current_month&order=ASC" ); |
例 3
这个例子解析如何删除一个完整的文章列表,并且进行分页处理。我们可以使用默认的 $query_string 告诉 query_posts() 显示所有文章列表。我们还可以自定义 posts_per_page 这个查询参数为 –1 到 任何数量 来设置每页显示的文章数。最后,你可能想使用 posts_nav_link() 来导航生成的文章存档。
1 |
query_posts( $query_string . '&posts_per_page=-1' ); |
例 4
如果你不需要使用 $query_string 变量,另一种方法是将所有的参数添加到一个数组中,即使在更加复杂的情况下,也清晰明了。上面 例 2 可以使用下面的代码实现:
1 2 3 4 5 6 7 |
$args = array( 'cat' => 22, 'year' => $current_year, 'monthnum' => $current_month, 'order' => 'ASC' ); query_posts( $args ); |
正如你所见,通过这种方式,所有的变量都放置在独立的行中,这就非常容易阅读了。
例 5
它甚至可以使用数组方式(例 4)来查询多个分类。只需提供分类别名(taxonomy slug),多个别名使用逗号隔开。在下面的例子中,我们会得到 Bruce Campbell 或 Chuck Norris 的movie文章:
1 2 3 4 5 6 |
$args = array( 'post_type'=> 'movie', 'actor' => 'Bruce Campbell, Chuck Norris', 'order' => 'ASC' ); query_posts( $args ); |
所在文件
query_posts() 包含在 wp-includes/query.php.
其他资源
为了更深入的讨论 WordPress 生成和处理查询,请阅读这些文章:
- Query Overview 和 Custom Queries
- 正确使用’pre_get_posts的自定义默认查询 – Bill Erickson – Customize the WordPress Query 或 John James Jacoby – Querying Posts Without query_posts
- 你不知道的查询 – Slides from WordCamp Netherlands 2012 by Andrew Nacin
- WordPress函数 之 query_posts用法汇总
相关函数
类: WP_Query – 详细的 WP_Query 类概述
类: $wpdb – 使用 $wpdb 对象的概述
函数: get_query_var()
函数: get_posts() – 一个专门返回文章数组的函数
函数: get_pages() – 一个专门返回页面数组的函数
函数: have posts() – 一个确定查询是否返回文章的条件
函数: the_post() – 用于自动设置查询后的循环
函数: rewind_posts() – 重置当前循环
函数: setup_postdata() – 为循环中的私有查询设置查询数据
函数: wp_reset_postdata() – 恢复以前的查询(通常在一环内循环)
函数: wp_reset_query()
函数: is_main_query() – 确保被改变的仅仅是主查询
动作钩子: pre_get_posts – 在执行之前修改 WordPress 的查询
过滤钩子: found_posts – 修改 WP_Query 对象的 found_posts 的值
教程: Displaying Posts Using a Custom Select Query
教程: Making Advanced Taxonomy Queries
- 原文:http://codex.wordpress.org/Function_Reference/query_posts
- 翻译:倡萌@WordPress大学 – WordPress函数:query_posts(查询文章)