WordPress多文章类型循环自定义筛选:文章+指定父ID页面
实现博客索引页同时展示文章与指定父级页面的方案
没问题!完全可以用单个WP_Query实现这个需求,甚至还能完美兼容WordPress的原生循环和分页函数。我给你两种实用的方案,你可以根据自己的场景选择:
方案一:修改主查询(推荐用于博客索引页主循环)
如果你的需求是替换博客索引页的默认主循环,直接用这个方案最省心,不需要额外处理分页逻辑,原生的have_posts()、previous_posts_link()都能直接用。
代码实现
把这段代码放到你的主题functions.php里:
add_action( 'pre_get_posts', 'custom_blog_index_posts' ); function custom_blog_index_posts( $query ) { // 只对前台的主查询、博客索引页生效,避免影响后台或其他页面 if ( $query->is_main_query() && ! is_admin() && $query->is_home() ) { // 设置同时查询文章和页面 $query->set( 'post_type', array('post', 'page') ); // 添加过滤器,只保留父ID为1、2、3的页面 add_filter( 'posts_where', 'filter_pages_by_parent_ids' ); } } function filter_pages_by_parent_ids( $where ) { global $wpdb; // 拼接条件:要么是文章类型,要么是页面类型且父ID在指定列表里 $where .= " AND ( {$wpdb->posts}.post_type = 'post' OR ( {$wpdb->posts}.post_type = 'page' AND {$wpdb->posts}.post_parent IN (1,2,3) ) )"; // 用完就移除过滤器,防止影响其他查询 remove_filter( current_filter(), __FUNCTION__ ); return $where; }
循环使用
然后在你的博客索引页模板(比如index.php)里,直接用原生循环就行:
<?php if ( have_posts() ) : ?> <?php while ( have_posts() ) : the_post(); ?> <!-- 可以根据内容类型加载不同模板,比如文章用content-post.php,页面用content-page.php --> <?php get_template_part( 'content', get_post_type() ); ?> <?php endwhile; ?> <!-- 原生分页函数直接用,不需要额外参数 --> <?php the_posts_pagination(); ?> <!-- 或者用前后页链接 --> <?php previous_posts_link( '« 上一页' ); ?> <?php next_posts_link( '下一页 »' ); ?> <?php else : ?> <?php get_template_part( 'content', 'none' ); ?> <?php endif; ?>
方案二:自定义WP_Query(适合页面内的独立循环)
如果你需要在页面的某个区域单独展示这个混合列表,而不影响主循环,就用这个方案。
代码实现
在你的模板文件里直接写这段代码:
// 标记当前是自定义查询,让过滤器只对它生效 $GLOBALS['custom_mixed_query'] = true; // 构建查询参数 $args = array( 'post_type' => array('post', 'page'), // 同时查询文章和页面 'posts_per_page' => get_option('posts_per_page'), // 沿用后台设置的每页数量 'paged' => get_query_var('paged') ? get_query_var('paged') : 1, 'orderby' => 'date', // 按发布时间排序 'order' => 'DESC' ); // 添加过滤器:只保留指定父ID的页面 add_filter( 'posts_where', 'filter_custom_pages_by_parent' ); function filter_custom_pages_by_parent( $where ) { global $wpdb; if ( isset( $GLOBALS['custom_mixed_query'] ) && $GLOBALS['custom_mixed_query'] ) { $where .= " AND ( {$wpdb->posts}.post_type = 'post' OR ( {$wpdb->posts}.post_type = 'page' AND {$wpdb->posts}.post_parent IN (1,2,3) ) )"; } return $where; } $custom_query = new WP_Query( $args ); // 移除过滤器,避免影响后续查询 remove_filter( 'posts_where', 'filter_custom_pages_by_parent' );
循环与分页
接着写循环和分页逻辑:
<?php if ( $custom_query->have_posts() ) : ?> <?php while ( $custom_query->have_posts() ) : $custom_query->the_post(); ?> <?php get_template_part( 'content', get_post_type() ); ?> <?php endwhile; ?> <!-- 分页需要传递自定义查询的max_num_pages参数 --> <?php the_posts_pagination( array( 'total' => $custom_query->max_num_pages, 'current' => max( 1, get_query_var('paged') ), ) ); ?> <!-- 前后页链接也要指定max_num_pages --> <?php previous_posts_link( '« 上一页', $custom_query->max_num_pages ); ?> <?php next_posts_link( '下一页 »', $custom_query->max_num_pages ); ?> <?php else : ?> <?php get_template_part( 'content', 'none' ); ?> <?php endif; ?> <!-- 一定要重置查询,恢复全局的$post对象 --> <?php wp_reset_postdata(); ?>
关键注意事项
- 过滤器的作用范围:一定要确保过滤器只针对目标查询生效,不然会影响后台的文章列表、其他页面的查询结果。
- 分页参数:自定义查询的分页必须传递
max_num_pages,不然分页函数会用全局主查询的分页数据,导致分页错误。 - 模板区分:用
get_template_part( 'content', get_post_type() )可以让文章和页面使用不同的模板文件,方便你定制不同的展示样式。
内容的提问来源于stack exchange,提问作者Arun John
相关产品推荐
相关产品推荐

