我们可以尝试使用the_posts
如果suppress_filters
查询变量为false,用于收集相关帖子ID。
然后我们可以使用pre_get_posts
钩子,在每个查询中排除accumulated post ID数组。
以下是流程的模式示例:
// Main query
$wp_query = new WP_Query( $args );
$wp_query->posts filtered and collected post IDs [1,2] from the \'post\' post type
// Sub query #1
$q1 = new WP_Query( [ \'wpse_exclude\' => true, ... ] );
pre_get_posts excludes accumulated [1,2]
$q1->posts filtered and collected [3,4]
// Sub query #2
$q2 = new WP_Query( [ \'wpse_exclude\' => true, ... ] );
pre_get_posts excludes accumulated [1,2,3,4]
$q2->posts filtered and collected [5,6]
// Sub query #3
$q3 = new WP_Query( $args );
No exclusion because \'wpse_exclude\' argument is missing
$q3->posts filtered and collected [7]
// Sub query #4
$q4 = new WP_Query( [ \'wpse_exclude\' => true, ... ] );
pre_get_posts excludes accumulated [1,2,3,4,5,6,7]
$q4->posts filtered and collected [8,9]
下面是演示类的可能构建块,可以帮助实现这一点:
这个init()
方法:
public function init( $collect_post_type = \'post\' )
{
// Collect post IDs
add_filter( \'the_posts\', [ $this, \'the_posts\' ] );
// Exclude accumulated post IDs in queries
add_action( \'pre_get_posts\', [ $this, \'pre_get_posts\' ] );
// Initialize accumulated post IDs for exclusion
$this->exclude_pids = [];
// Collect post IDs only from this post type
$this->collect_post_type = $collect_post_type;
}
The
pre_get_posts()
方法:
public function pre_get_posts( \\WP_Query $q )
{
if(
$q->is_home() // Target the home page
&& $q->get( \'wpse_exclude\' ) // Target queries with wpse_exclude set as true
// && ... etc
) {
// Exclude accumulated set of post IDs
if( ! empty( $this->exclude_pids ) )
$q->set( \'post__not_in\', $this->exclude_pids );
}
}
在这里,我们还应该考虑保留以前的
post__not_in
参数。
这个the_posts()
方法:
public function the_posts( array $posts )
{
// Collect post IDs from \'post\' post type and merge to the $pids array
$this->exclude_pids = array_merge(
$this->exclude_pids ,
(array) wp_filter_object_list(
$posts,
[ \'post_type\' => $this->collect_post_type ],
\'AND\',
\'ID\'
)
);
return $posts;
}
希望您可以根据自己的需要进行调整。