Wordpress query_posts在排除类别时按日期排序

时间:2014-12-16 12:11:35

标签: wordpress

我希望排除某个类别,并使用query_posts按日期对结果进行排序,同时保留现有查询参数并按日期排序结果。

根据Wordpress文档,我应该按以下方式添加(或覆盖)参数:

global $query_string;
query_posts( $query_string . '&orderby=date&order=ASC&cat=-1' );

结果是正确的,但是按日期排序它们不起作用(ASC和DESC)。

只对结果进行排序才能正常工作:

global $query_string;
query_posts( $query_string . '&orderby=date&order=ASC' );

仅排除某个类别而未订购结果,效果正常:

global $query_string;
query_posts( $query_string . '&cat=-1 );

还包括某些类别并订购结果正常:

global $query_string;
query_posts( $query_string . '&orderby=date&order=ASC&cat=2' );

当然,我可以先构建一个正确的类别数组,然后在query_posts中使用这些类别。如下所示:

$include = array();

$categories = get_categories( array('exclude' => 1) );

foreach ( $categories as $category ) {
    $include[] = $category->term_id;
}

但我无法弄清楚为什么在使用query_posts时,排除类别和按日期排序的组合不起作用。

使用Wordpress版本3.9.1和4.0.1进行测试。两者都给出了相同的结果。

这是Wordpress中的错误还是我的代码中的错误?

编辑:

根据评论测试了WP_Query和pre_get_posts,但两者都返回与query_posts相同的结果。

WP_Query示例

$args = array(
    'category__not_in'  => array(1),
    'post_type'         => 'post',
    'orderby'           => 'date',
    'order'             => 'ASC',
);

// The Query
$query = new WP_Query( $args );

pre_get_posts示例

function exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'orderby', 'date' );
        $query->set( 'order', 'ASC' );
        $query->set( 'cat', '-1' );
    }
}
add_action( 'pre_get_posts', 'exclude_category' );

除非排除某个类别,否则一切正常。

2 个答案:

答案 0 :(得分:2)

经过一番研究后,我认为问题是由生成的SQL查询引起的(使用query_posts或WP_Query或pre_get_posts是相同的)。

按日期排序并使用以下代码排除类别时:

query_posts( $query_string . '&orderby=date&order=ASC&cat=-1' );

执行以下查询:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
WHERE 1=1 
AND ( wp_posts.ID NOT IN ( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN (1) ) ) 
AND wp_posts.post_type = 'post' 
AND (wp_posts.post_status = 'publish') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date ASC 
LIMIT 0, 10 

在这种情况下,ORDER BY不与GROUP BY结合使用。您可以在Stackoverflow上的其他问题中找到更多相关信息。例如:Using ORDER BY and GROUP BY together

我认为最好的解决方法是首先构建一个需要包含的类别数组。然后在query_posts:

中使用此数组
$include = array();

// Get all categories except category_id 1 (or other).
$categories = get_categories( array('exclude' => 1) ); 

// Loop categories to build array with category id's
foreach ( $categories as $category ) {
    $include[] = $category->term_id;
}

// Query posts: order by date and only include categories from array
query_posts( $query_string . '&orderby=date&order=ASC&cat=' . implode(',',$include) );

生成的查询将是(2和3是包含的类别ID'):

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
WHERE 1=1 
AND ( wp_term_relationships.term_taxonomy_id IN (2,3) ) 
AND wp_posts.post_type = 'post' 
AND (wp_posts.post_status = 'publish') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date ASC
LIMIT 0, 10

在这种情况下,由于不同的查询构建(使用INNER JOIN),按日期排序将正常工作。

答案 1 :(得分:0)

您应该尝试声明new WP_Query而不是query_posts()