Query_posts是WordPress主题开发中最实用的语句。在query_posts的作用下,WordPress的Loop循环才能够调用并显示所有文章内容。Query_posts可以根据你的要求,通过各种各样的方式灵活地检索并过滤日志或页面。你甚至可以利用query_posts来查询某一分类目录下某个作者发表的、带有某个标签的特定数量文章,下面大挖要介绍的是一些更详细更有趣的用法。
注意事项
首先要注意的是,使用query_posts的最好方法.就是不要用它。
Query_posts中说到: query_posts函数仅用于修改主页循环(Loop),而不是一种在页面上生成次级循环的手段。如果你希望在主循环外另外生成循环,应该新建独立的WP_Query对象,用这些对象生成循环。在主循环外的循环上使用query_posts会导致主循环运行偏差,并可能在页面上显示出你不希望看到的内容。
最恰当的方法是使用query查询类。
1 2 3 4 5 6 7 8 |
<?php $query = 'posts_per_page=10'; $queryObject = new WP_Query($query); // The Loop… if ($queryObject->have_posts()) { while ($queryObject->have_posts()) { $queryObject->the_post(); the_title(); the_content(); } } ?> |
不同调用方法
传统的文章调用方法是以查询字符串形式传递query_posts参数(如variable1=value1&variable2=value2&…),不过后来有了新方法——用数组来设置查询参数。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php // GOOD // select 10 posts from category 1 $query = 'posts_per_page=10&cat=1'; $queryObject = new WP_Query($query); // The Loop… // BETTER $query = array ( 'posts_per_page' => 10, 'cat' => 1 ); $queryObject = new WP_Query($query); // The Loop… ?> |
关于日志顺序
默认情况下WordPress日志是按日期顺序排列的,这也是大多数人的需求,不过如果能更改默认的排列顺序那就更好了。 例如你可以随意调用几篇日志,让它们显示在侧边栏。 WordPress 2.9引入了以评论的数量多寡给文章排序的功能,这样就可以更方便地向访客显示最受欢迎的文章….不过这里为了使用query_posts,我们假设一下 不使用WordPress的这个功能。
1 2 3 4 5 6 |
<?php // select posts ordered by comment_count $query = 'orderby=comment_count'; $queryObject = new WP_Query($query); // The Loop… ?> |
Meta值
Post meta函数的实用性也很强, 我们可以利用下面的代码来显示最受欢迎的文章:
1 2 3 4 5 6 7 |
<?php // grab posts by post count ordered in descending order (most votes first) $query = 'meta_key=vote_count&orderby=meta_value&order=DESC'; $queryObject = new WP_Query($query); // The Loop… ?> |
日志、页面、附件
你可以按文章类型调用自己想要的日志、页面或附件。 对附件的调用可能是最有趣但同时被使用频率也是最低的一个。 利用下面的代码(与上文中提到的顺序参数),你就可以根据自己的喜好在网站上显示各种媒体文件了:
1 2 3 4 5 6 |
<?php // grab 1 random attachment $query = 'post_type=attachment&orderby=rand&posts_per_page=1'; $queryObject = new WP_Query($query); // The Loop… ?> |
置顶文章
WordPress在 2.7版本中引入了文章置顶功能。 这使用户选定的文章能够不受时间的排序标准,总是显示在文章列表的最上方。 实现文章置顶的标准操作是,将这些文章添加到所返回数据列表的开始部分。 你可能需要对置顶文章过滤器函数进行以下操作:
默认情况——调用最先添加的置顶文章
只调用置顶文章(适用于杂志型主题)
按正常情况调用文章,忽略文章的置顶状态
要调用所有置顶文章:
1 2 3 4 5 |
<?php $query = 'post_type=attachment&orderby=rand&posts_per_pages=1'; $queryObject = new WP_Query($query); // The Loop… ?> |
要忽略置顶文章——让所有文章按正常排序方式显示:
1 2 3 4 5 |
<?php $query = array( 'post__not_in' => get_option('sticky_posts') ); $queryObject = new WP_Query($query); // The Loop… ?> |
抓取所有文章
你可以用几种不同的方法在网站地图和存档页等需要显示所有已发布文章的地方调用所有文章。 要调用所有已发布的文章,可以使用下面的这段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php // showposts is the traditional way of doing it, but it's now deprecated so could be removed at any time // there are still lots of themes that use showposts (including my own) so it's worth switching over as soon as you can just in case $query = 'showposts=-1'; $queryObject = new WP_Query($query); // The Loop… // the new way to do it $query = 'posts_per_page=-1'; $queryObject = new WP_Query($query); // The Loop… // must admit I have never tried this myself but according to the documentation it will work :) $query = 'nopaging=true'; $queryObject = new WP_Query($query); // The Loop… ?> |
钩子(hooks)和过滤器(filter)
Query_posts函数一个鲜有人知的功能就是,你可以用它勾入已生成的查询。 这种行为可能有些冒险,不过实用价值很高。 WordPress有一些可以用来修改查询要素的过滤器(filter)函数。
根据对WordPress filter函数的介绍,可以用在文章查询和调用上的filter包括:
post_limits
应用于查询的LIMIT语句,该语句可返回日志数组
posts_distinct
允许插件将DISTINCTROW语句加入查询,该查询可返回日志数组
posts_groupby
应用于查询的GROUP BY语句,该语句可返回日志数组(通常情况下该数组为空)
posts_join_paged
应用于查询的JOIN语句。在计算出分页后,该查询返回日志列表(分页并不影响JOIN语句,因此该函数相当于posts_join)
posts_orderby
应用于查询的ORDER BY语句,该语句可返回日志数组
posts_request
在执行查询前,应用于将返回日志数组的整个SQL查询
posts_where_paged
应用于查询的WHERE语句。在计算出分页后,该查询返回日志数组(分页并不影响WHERE语句,因此该函数相当于posts_where)
posts_join
应用于查询的JOIN语句,该语句可返回日志数组 该过滤器函数与post_where函数一并为JOIN语句添加了一个数据库表。
posts_where
应用于查询的WHERE语句,该语句可返回日志数组
Query_posts参数数量极多且复杂,大多数人没有必要了解这些。但有时如果你想用数字型meta值来为一次查询排序,却发现meta值是字 符串字段类型的(即,查询的顺序是1, 10, 11, 2, 23, 3,而你希望是按数字大小来排序:1,2,3,10,11,23)。 这时你可以用下面的代码达到效果:
1 2 3 4 5 |
add_filter ('posts_orderby', 'bm_featureHomeFilterOrder'); function bm_featureHomeFilterOrder ($order = ”) { global $wpdb; $field = $wpdb->postmeta . '.meta_value'; $order = str_replace($field, 'CAST(' . $field . ' AS UNSIGNED)', $order); return $order; } |
文章回转
文章回转功能使用户可以运行“WordPress循环”后重设主循环,然后再重新运行主循环。 调用文章回转也很容易。
1 2 3 4 5 6 7 8 9 10 |
<?php rewind_posts(); ?> 那么要使用它你需要: <?php $query = 'posts_per_page=10'; $queryObject = new WP_Query($query); // The Loop… rewind_posts(); // The Loop… ?> |
不显示某些文章(隐藏重复内容)
最后这个方法曾经在WebLogToolsCollection上 出现过。 其原理是当用户在某一个页面上使用多个WordPress循环时,用代码阻止重复内容被链接。例如,当你的网站首页显示了最新发表的日志后会继续显示分 类,如果隐藏重复内容,分类下将隐藏已经显示的最新发表的日志, 从而让更多内容显示在主页上。这是WebLogToolsCollection上的原始代码:$bmIgnorePosts = array();
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 43 44 45 46 47 48 49 50 51 52 53 54 55 |
/** * add a post id to the ignore list for future query_posts */ function bm_ignorePost ($id) { if (!is_page()) { global $bmIgnorePosts; $bmIgnorePosts[] = $id; } } /** * reset the ignore list */ function bm_ignorePostReset () { global $bmIgnorePosts; $bmIgnorePosts = array(); } /** * remove the posts from query_posts */ function bm_postStrip ($where) { global $bmIgnorePosts, $wpdb; if (count($bmIgnorePosts) > 0) { $where .= ' AND ' . $wpdb->posts . '.ID NOT IN(' . implode (',', $bmIgnorePosts) . ') '; } return $where; } add_filter ('posts_where', 'bm_postStrip'); 下面是改进后的: <?php // set the query $query = 'posts_per_page=10'; // loop 1 – display most recent 10 posts $queryObject = new WP_Query($query); if ($queryObject->have_posts()) { while ($queryObject->have_posts()) { bm_ignorePost($queryPost->post->ID); $queryObject->the_post(); the_title(); the_content(); } } // loop 2 – same query, get the next 10 posts $queryObject = new WP_Query($query); if ($queryObject->have_posts()) { while ($queryObject->have_posts()) { bm_ignorePost($queryPost->post->ID); $queryObject->the_post(); the_title(); the_content(); } } ?> |