在WordPress中禁止输出特定分类的文章

在Wordpress中进行数据筛选通常使用add_filter,主查询进程是WP_Query,但是查了之后还是使用 'pre_get_posts'这个action. $query->set()中可以进行各种数据的筛选,如果是排除特定分类的文章,那么该参数是 'category__not_in',如果有其他的筛选需求,诸如author__not_intag_slug__in等参数(parameters)可以参见WP_Query页面,该参数是一个Array。

WordPress中的默认分类是可以在后台修改的,其数据存储在wp_options表,可以通过get_option('default_category')进行查询。为了适应那些修改了默认分类的情况,我们可以将 'category__not_in'的值设定为array( get_option('default_category') )

如果仅止于此的话,那么可能会在很多页面(无论前后台)都无法看到默认分类的文章了,这样不利于我们对数据的管理,所以我们应该指定在那些情况适用这种筛选设定,比如要在首页的主循环中应用这设定,其代码如下:

// 在默认分类中的文章不在首页输出中显示
add_action( 'pre_get_posts', 'xdm_exclude_default_category_posts' );
function xdm_exclude_default_category_posts($query) {
	if ( $query->is_home() && $query->is_main_query() ) { //限定在home页面和main_query
		$query->set( 'category__not_in', array( get_option('default_category') ) );
	}
}

如果依照上述的代码,默认分类的文章在首页中将不显示,但是在其他前台页面中或者后台hai是可以看得到。但这个并不符合我的实际需求,我仅仅需要该分类文章其在前台特定的某个页面显示,并且在后台也能正常显示,那么我们的逻辑可以先在所有的逻辑中排除该分类文章,然后在限定指定的页面显示这些文章。代码如下:

// 在默认分类中的文章在后台和默认分类页输出中显示
add_action( 'pre_get_posts', 'xdm_exclude_default_category_posts' );
function xdm_exclude_default_category_posts($query) {
    $def_cat_ID = get_option('default_category');
    $query->set( 'category__not_in', array( $def_cat_ID ) );
	if ( $query->is_admin() || ($query->is_category( $def_cat_ID ) && $query->is_main_query() ) ) { //限定在分类页面和后台
		$query->set( 'category__not_in', [] );
	}
}

另一种思路是限定在前端的默认分类归档页面才予以显示:

function xdm_exclude_default_category_posts($query) {
	if ( $query->is_front_page() && !($query->is_category( $def_cat_ID ))) { //限定在前台的分类页面
		$query->set( 'category__not_in', [get_option('default_category')] );
	}
}

需要注意的是is_front_page(),不能用is_front(),因为没有这个选项。

问题来了,Wordpress App也同样受影响了

wp_is_json_request(): bool
Checks whether current request is a JSON request, or is expecting a JSON response.
@https://developer.wordpress.org/reference/functions/wp_is_json_request/

一开始我认为这个app使用了rest api,于是一再查找判断来源为 rest api 请求的函数,但总是徒劳无功,该app的界面始终和网页端保持一致。看来这个App的做法无法绕过pre_get_posts.