You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:26:27