先来看一段示例代码,代码很简单,就是从后台设置中获取要排除的分类数组,然后在主查询中排除对应的分类。实际使用中,大部分时候也是可以正常使用的。不过我在实际使用中发现,这种写法存在很大的兼容性问题。例如再次挂钩到 pre_get_posts
钩子中,并且一样是对 category__not_in
属性进行设置,就会发生属性被覆盖的问题,也就是挂钩两次,只有一次生效。
// 全部查询中排除指定分类
function wper_exclude_category( $query ) {
$no_cat = (get_option('wper_not_cat')) ? get_option('wper_not_cat') : false;
if ( $query->is_main_query() ){
if ($no_cat) {
$query->set( 'category__not_in', $no_cat );
}
}
}
add_action( 'pre_get_posts', 'wper_exclude_category' );
不知道其他人怎么解决这个问题的,我查询官方文档后,做了如下修改,测试可以正常使用。逻辑也很简单,就是在 $query->set
之前,先获取原来的属性数组,然后跟新的数组合并后,再 $query->set
。代码如下:
// 全部查询中排除指定分类
function wper_exclude_category( $query ) {
$no_cat = (get_option('wper_not_cat')) ? get_option('wper_not_cat') : false;
if ( $query->is_main_query() ){
if ($no_cat) {
$has_no_cat = $query->get('category__not_in', array());//获取原来的数据,没有的话,返回空数组
$all_no_cat = array_merge($no_cat, $has_no_cat);//合并数组
$query->set( 'category__not_in', $all_no_cat );//设置数据为合并后的数组
}
}
}
add_action( 'pre_get_posts', 'wper_exclude_category' );