修改前$query
我们首先要找出哪些帖子需要排除,哪些帖子需要两个查询(如果我能想出一种方法,我会更新答案)。
第一个将获取所有父事件的不同ID的列表,例如-
SELECT DISTINCT wp_posts.post_parent FROM wp_posts WHERE wp_posts.post_type = "event" AND wp_posts.post_type = "publish" AND wp_posts.post_parent != 0
下一步将获取所有没有任何子级的顶级事件的ID(例如,那些不在我们使用上一个查询生成的列表中的事件),例如-
SELECT fgw_2_posts.ID FROM wp_posts WHERE wp_posts.post_type = "event" AND wp_posts.post_type = "publish" AND wp_posts.post_parent = 0 AND wp_posts.ID NOT IN (1,2,3)
最后,我们可以根据需要设置$查询-
$query->set(\'post__not_in\', $loners);
$query->set(\'post_parent\', 0);
这是完整的代码-
add_action(\'pre_get_posts\', \'my_exclude_parents_without_children\');
function my_exclude_parents_without_children($query){
global $wpdb;
if($query->is_main_query() && !is_admin()) :
if(is_post_type_archive(\'event\')) :
/** First grab the ID\'s of all post parents */
$my_query = $wpdb->prepare(\'SELECT DISTINCT %1$s.post_parent FROM %1$s WHERE %1$s.post_type = "event" AND %1$s.post_status = "publish" AND %1$s.post_parent != 0\', $wpdb->posts);
$parents = $wpdb->get_col($my_query);
/** Next grab the ID of all posts who do not have children (we\'ll call them \'loners\') */
$my_query = $wpdb->prepare(\'SELECT %1$s.ID FROM %1$s WHERE %1$s.post_type = "event" AND %1$s.post_status = "publish" AND %1$s.post_parent = 0\', $wpdb->posts, join(\',\', $parents));
if(!empty($parents)) : // Ensure that there are events with children to exclude from this query
$my_query.= $wpdb->prepare(\' AND %1$s.ID NOT IN (%2$s)\', $wpdb->posts, join(\',\', $parents));
endif;
$loners = $wpdb->get_col($my_query);
/** Now exclude the \'loners\' */
$query->set(\'post__not_in\', $loners);
$query->set(\'post_parent\', 0);
endif;
endif;
}