如何在WordPress的WP_Query中设置特定文章类型的出现频次?
WordPress 按固定频次展示特定文章类型的实现方案
你提到的单独查询再重组的思路其实是最可控、易维护的方案,不过可以优化实现逻辑,下面给你两种实用的实现方式:
方案一:分查询+有序重组(推荐)
核心是分别获取足够数量的非post类型(video、course)和post类型文章,再按「2条非post + 1条post」的规则拼接成最终数组,逻辑清晰且容易调整。
示例代码:
// 获取非post类型文章(可自定义排序、数量) $non_post_query = new WP_Query([ 'post_type' => ['video', 'course'], 'posts_per_page' => 8, // 比如要展示12条,对应8条非post 'orderby' => 'date', 'order' => 'DESC' ]); $non_posts = $non_post_query->posts; // 获取post类型文章 $post_query = new WP_Query([ 'post_type' => 'post', 'posts_per_page' => 4, // 对应总条数的1/3 'orderby' => 'date', 'order' => 'DESC' ]); $posts = $post_query->posts; // 按规则重组数组 $final_posts = []; $non_post_idx = 0; $post_idx = 0; $total_items = 12; // 设定总展示条数 for ($i = 0; $i < $total_items; $i++) { // 每第3个位置插入post类型 if (($i + 1) % 3 === 0 && isset($posts[$post_idx])) { $final_posts[] = $posts[$post_idx]; $post_idx++; } else if (isset($non_posts[$non_post_idx])) { $final_posts[] = $non_posts[$non_post_idx]; $non_post_idx++; } } // 循环输出文章 foreach ($final_posts as $post) { setup_postdata($post); // 这里写你的文章输出逻辑,比如: echo '<h3>' . get_the_title() . '</h3>'; echo '<p>类型:' . $post->post_type . '</p>'; } wp_reset_postdata();
这个方案的优势:
- 可分别控制不同类型文章的排序规则和数量
- 频次调整简单(比如改成每4条插1条post,只需把
% 3改成% 4) - 逻辑直观,后期维护成本低
方案二:主查询后重新排序结果
如果不想分两次查询,可以先一次性获取所有类型的文章,再在PHP层面分离类型后重组,适合数据源中post数量刚好匹配需求的场景:
示例代码:
// 获取所有类型的文章 $all_query = new WP_Query([ 'post_type' => ['video', 'course', 'post'], 'posts_per_page' => 12, 'orderby' => 'date', 'order' => 'DESC' ]); // 分离不同类型的文章 $non_posts = []; $posts = []; foreach ($all_query->posts as $post) { $post->post_type === 'post' ? $posts[] = $post : $non_posts[] = $post; } // 按规则重组数组(逻辑同方案一) $final_posts = []; $n_idx = 0; $p_idx = 0; for ($i = 0; $i < 12; $i++) { if (($i + 1) % 3 === 0 && isset($posts[$p_idx])) { $final_posts[] = $posts[$p_idx]; $p_idx++; } else if (isset($non_posts[$n_idx])) { $final_posts[] = $non_posts[$n_idx]; $n_idx++; } } // 循环输出 foreach ($final_posts as $post) { setup_postdata($post); echo '<h3>' . get_the_title() . '</h3>'; echo '<p>类型:' . $post->post_type . '</p>'; } wp_reset_postdata();
注意:如果查询结果中post类型占比过高,剩余的post会无法按规则插入,需要提前确保数据源数量匹配。
不推荐的方案:数据库层面修改排序
虽然可以通过posts_orderby过滤器修改SQL排序逻辑,但需要计算行号、分组排序,不仅实现复杂,还容易导致分页错误、排序混乱,维护成本极高,不建议使用。
内容的提问来源于stack exchange,提问作者Azaz Khan
相关产品推荐
相关产品推荐

