解决WP_Query短代码中多分类文章仅单次输出的问题
问题根因
原代码遍历文章所属分类的逻辑存在问题:遍历$nav_arr时每次覆盖$nav变量,最终仅保留最后一个分类的名称,文章内容也仅被插入到该最后分类的分组中,因此归属多分类的文章只会在一个分类下展示。
修复后的完整代码
function filter_shortcode($atts, $content = null) { global $post; $attributes = shortcode_atts( array( 'type' => '', 'num' => -1 ), $atts); $args = array( 'post_type' => $attributes["type"], 'posts_per_page' => $attributes["num"] ); $post_query = new WP_Query($args); $master_array = array(); // 初始化输出变量避免未定义警告 $navigation = ''; $output_outer = ''; if ($post_query->have_posts() ) { while ($post_query->have_posts()) { $post_query->the_post(); $nav_arr = wp_get_post_terms( get_the_ID(), 'solutions_category' ); // 先生成和分类无关的文章公共内容,避免重复计算 $box_tooltip = '<div>Lorem Ipsum</div>'; $info_box_title = '<h5 style="margin-bottom: 0;">' . strtoupper($post->post_title) . '</h5>'; // 遍历所有所属分类,每个分类下都插入当前文章 foreach($nav_arr as $nav_value ) { $nav = $nav_value->name; if (!isset($master_array[$nav])) { $master_array[$nav] = array(); } array_push( $master_array[$nav], [ 'icon_title' => $info_box_title, 'tooltip' => $box_tooltip, ] ); } } // End of while have_posts wp_reset_postdata(); /* Foreach master array */ foreach ((array)$master_array as $master_key => $master_value) { /* Navigation */ $navigation .= '<div>'. $master_key .'</div>'; foreach($master_value as $query_key => $query_value) { $output_inner = ''; foreach ($query_value as $object_key => $object_value) { $output_inner .= $object_value; } /* Content 这里的class自动绑定对应分类名,符合要求 */ $output_outer .= '<div class="'. $master_key .'">'. $output_inner .'</div>'; } // end foreach mastervalue } // end foreach master } // end if have posts return ' <div style="margin-bottom: 30px;">'. $navigation .'</div> <div>'. $output_outer .'</div> '; } add_shortcode('cpt_filter', 'filter_shortcode');
核心修改说明
- 将文章公共内容(标题、提示框)的生成逻辑移到分类遍历之前,避免重复生成相同内容
- 把文章插入分类分组的逻辑放到分类遍历内部,每遍历到一个文章所属的分类,就把文章插入对应分类的分组一次
- 原有输出逻辑完全保留,输出的文章容器class会自动继承对应分类的名称,符合需求
- 新增了输出变量初始化逻辑,避免PHP报未定义变量的警告
内容的提问来源于stack exchange,提问作者la_petite_kozel
相关产品推荐
相关产品推荐

