如何在WordPress全局菜单中调取自定义文章类型collection的父子级标题
可行实现方案
你可以直接在父级文章循环内部嵌套子级查询,通过传入当前父级文章ID作为post_parent参数捞出对应子级内容,修改后的完整代码如下:
<?php $parent_loop = new WP_Query( array( 'post_type' => 'collection', 'orderby' => 'menu_order', // 注意原代码参数名写错了,是orderby不是order_by 'order' => 'ASC', 'posts_per_page' => -1, 'post_parent' => 0 ) ); ?> <?php while ( $parent_loop->have_posts() ) : $parent_loop->the_post(); ?> <div class="large-2"> <?php the_title(); /* 父级标题 */ ?> <?php // 子级查询 $child_loop = new WP_Query( array( 'post_type' => 'collection', 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => -1, 'post_parent' => get_the_ID(), // 传入当前父级ID作为筛选条件 'no_found_rows' => true, // 不需要分页的情况下加这个参数提升查询性能 ) ); if ( $child_loop->have_posts() ) : ?> <ul class="child-collection"> <?php while ( $child_loop->have_posts() ) : $child_loop->the_post(); ?> <li><?php the_title(); ?></li> <?php endwhile; ?> </ul> <?php endif; // 重置post对象,避免污染全局变量 wp_reset_postdata(); ?> </div> <?php endwhile; // 父级循环结束后也要重置 wp_reset_postdata(); ?>
关键改动说明
- 修正了原代码中写错的排序参数:
order_by改为WordPress官方规范的orderby - 新增子级查询时传入当前父级文章ID
get_the_ID()作为post_parent参数,精准筛选对应子级 - 新增
wp_reset_postdata()调用,避免嵌套循环导致全局$post对象异常 - 新增无子级内容时的判断,没有子级的父级不会输出空的列表结构
大数据量场景优化方案
如果你的collection文章数量超过100篇,嵌套循环会产生N+1次数据库查询,性能较差,可以改用一次性捞出所有collection文章再分组的方式实现:
// 一次性查询所有collection文章 $all_collections = get_posts( array( 'post_type' => 'collection', 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => -1, ) ); // 按父级ID分组 $collections_by_parent = []; foreach ( $all_collections as $post ) { $collections_by_parent[ $post->post_parent ][] = $post; } // 遍历父级输出 foreach ( $collections_by_parent[0] as $parent_post ) { setup_postdata( $parent_post ); ?> <div class="large-2"> <?php echo get_the_title( $parent_post ); ?> <?php if ( isset( $collections_by_parent[ $parent_post->ID ] ) ) : ?> <ul class="child-collection"> <?php foreach ( $collections_by_parent[ $parent_post->ID ] as $child_post ) : ?> <li><?php echo get_the_title( $child_post ); ?></li> <?php endforeach; ?> </ul> <?php endif; ?> </div> <?php } wp_reset_postdata();
这种方案只需要1次数据库查询,性能远高于嵌套循环的写法。
内容的提问来源于stack exchange,提问作者Ronan
相关产品推荐
相关产品推荐

