8. 钩子(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)。 这时你可以用下面的代码达到效果:
<code>
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; }
9. 文章回转
文章回转功能使用户可以运行“WordPress循环”后重设主循环,然后再重新运行主循环。 调用文章回转也很容易。
<code>
<?php rewind_posts(); ?>
那么要使用它你需要:
<?php
$query = 'posts_per_page=10';
$queryObject = new WP_Query($query);
// The Loop…
rewind_posts();
// The Loop…
?>
10. 不显示某些文章(隐藏重复内容)
最后这个方法曾经在WebLogToolsCollection上 出现过。 其原理是当用户在某一个页面上使用多个WordPress循环时,用代码阻止重复内容被链接。例如,当你的网站首页显示了最新发表的日志后会继续显示分 类,如果隐藏重复内容,分类下将隐藏已经显示的最新发表的日志, 从而让更多内容显示在主页上。这是WebLogToolsCollection上的原始代码:$bmIgnorePosts = array();
<code>
/**
* 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();
}
}
?>

