如何按父文章排序显示关联最新子文章?Posts 2 Posts插件求助
解决方案:按关联的最新子文章排序父文章列表
没问题,这个需求完全可以实现!你当前的代码是按Drama自身的发布日期排序,但核心需求是按每个Drama关联的最新Episode的发布日期来排序Drama归档页的列表,同时每个Drama只展示最新的那一条Episode。下面是具体的实现步骤和修改后的代码:
核心思路
- 先获取所有已发布的Drama文章;
- 为每个Drama获取其关联的最新Episode的发布日期,作为排序依据;
- 根据这个Episode日期对Drama数组进行降序排序(最新的Episode对应的Drama排在最前面);
- 处理分页逻辑,因为排序后的数组需要手动切割分页数据;
- 最后用
each_connected()关联每个Drama的最新Episode,完成渲染。
修改后的完整代码
<?php global $post; $paged = (get_query_var('page')) ? get_query_var('page') : 1; $posts_per_page = 12; // 1. 获取所有已发布的Drama $all_dramas = get_posts(array( 'post_type' => 'drama', 'posts_per_page' => -1, // 获取全部Drama,后续再处理分页 'post_status' => 'publish', 'orderby' => 'post_date', 'order' => 'DESC' )); // 2. 为每个Drama获取最新Episode的日期,用于排序 $dramas_with_episode_date = array(); foreach ($all_dramas as $drama) { // 获取当前Drama关联的最新Episode $latest_episode = p2p_type('drama_to_episode')->get_connected($drama, array( 'posts_per_page' => 1, 'post_status' => 'publish', 'orderby' => 'post_date', 'order' => 'DESC' ))->posts; // 记录Drama和对应的最新Episode日期(如果没有Episode则用Drama自身日期) $episode_date = !empty($latest_episode) ? $latest_episode[0]->post_date : $drama->post_date; $dramas_with_episode_date[] = array( 'drama' => $drama, 'sort_date' => $episode_date ); } // 3. 按最新Episode日期降序排序Drama数组 usort($dramas_with_episode_date, function($a, $b) { return strtotime($b['sort_date']) - strtotime($a['sort_date']); }); // 4. 处理分页:切割当前页的Drama数据 $total_dramas = count($dramas_with_episode_date); $offset = ($paged - 1) * $posts_per_page; $current_page_dramas = array_slice($dramas_with_episode_date, $offset, $posts_per_page); // 5. 将处理后的Drama数据转为WP_Query对象,方便后续使用each_connected $drama_post_ids = wp_list_pluck($current_page_dramas, 'ID', 'drama->ID'); $the_query = new WP_Query(array( 'post_type' => 'drama', 'posts_per_page' => $posts_per_page, 'post__in' => array_keys($drama_post_ids), 'orderby' => 'post__in', // 保持我们排序后的顺序 'post_status' => 'publish' )); // 6. 关联每个Drama的最新Episode $extra = array( 'posts_per_page' => 1, 'post_status' => 'publish', 'orderby' => 'post_date', 'order' => 'DESC' ); p2p_type('drama_to_episode')->each_connected($the_query, $extra, 'episode'); ?> <div class="last_episodes loaddub"> <ul class="items"> <?php if ($the_query->have_posts()) : ?> <?php while ($the_query->have_posts()) : $the_query->the_post(); ?> <li> <div class="img"> <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"> <img alt="<?php the_title(); ?>" itemprop="photo" src="<?php echo get_the_post_thumbnail_url(); ?>"> </a> <div class="type"><img src="<?php echo get_stylesheet_directory_uri(); ?>/images/SUB.png"></div> </div> <?php // 只显示关联的最新Episode if (!empty($post->episode)) { $latest_episode = $post->episode[0]; setup_postdata($latest_episode); ?> <p class="name"> <a href="<?php echo get_permalink($post->ID); ?>" title="<?php get_the_title($post->ID); ?>"> <?php get_the_title($post->ID); ?> </a> </p> <p class="episode"> <?php echo get_field('short_name', $latest_episode->ID); ?> </p> <?php wp_reset_postdata(); // 重置到当前Drama的post数据 } ?> </li> <?php endwhile; ?> <?php wp_reset_postdata(); ?> <?php else: ?> <p><?php esc_html_e('Sorry, no posts matched your criteria.'); ?></p> <?php endif; ?> </ul> </div>
关键说明
- 排序逻辑:通过
usort()自定义排序规则,用每个Drama最新Episode的日期作为排序键,确保最新更新的Drama排在最前面; - 分页处理:因为先获取了全部Drama再排序,所以需要手动计算偏移量来切割当前页的数据,保持分页功能正常;
- 数据关联:使用
each_connected()时指定posts_per_page=1,确保每个Drama只拉取最新的一条Episode; - 全局变量处理:在遍历Episode时使用
setup_postdata()和wp_reset_postdata(),避免全局$post变量混乱。
内容的提问来源于stack exchange,提问作者Zubair Mushtaq
相关产品推荐
相关产品推荐

