如何实现WordPress中仅在子分类生效的PREV、NEXT分页(Gallery CPT)
实现仅在当前子分类内的上一篇/下一篇分页
可以实现,默认的get_previous_post()和get_next_post()函数在$in_same_term=true时会包含父分类及所有关联子分类,这是WordPress分类层级关联逻辑导致的。要限制仅在当前子分类内分页,需要手动指定目标子分类并排除父类关联,以下是两种可行方案:
方案一:自定义WP_Query查询(推荐,逻辑清晰)
直接通过get_posts()构造精准查询,只获取当前子分类下的文章:
<?php // 获取当前文章ID $current_post_id = get_the_ID(); // 筛选当前文章所属的子分类(排除顶级父分类) $current_child_terms = wp_get_post_terms( $current_post_id, 'category', array( 'fields' => 'ids', 'parent__not_in' => array(0) // 只取有父类的子分类 ) ); if (!empty($current_child_terms)) { // 取第一个子分类(若文章属于多个子分类,可根据需求调整逻辑) $target_term_id = $current_child_terms[0]; // 查询上一篇文章 $prev_post = get_posts(array( 'post_type' => 'gallery', // 替换为你的自定义文章类型slug 'posts_per_page' => 1, 'order' => 'DESC', 'orderby' => 'date', 'post__not_in' => array($current_post_id), 'tax_query' => array( array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $target_term_id, 'include_children' => false // 关键:不包含当前分类的子分类(若有的话) ) ) )); // 查询下一篇文章 $next_post = get_posts(array( 'post_type' => 'gallery', 'posts_per_page' => 1, 'order' => 'ASC', 'orderby' => 'date', 'post__not_in' => array($current_post_id), 'tax_query' => array( array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $target_term_id, 'include_children' => false ) ) )); // 输出上一篇链接 if ($prev_post) { echo '<a href="' . get_permalink($prev_post[0]->ID) . '">上一篇:' . get_the_title($prev_post[0]->ID) . '</a>'; } // 输出下一篇链接 if ($next_post) { echo '<a href="' . get_permalink($next_post[0]->ID) . '">下一篇:' . get_the_title($next_post[0]->ID) . '</a>'; } } ?>
方案二:通过过滤器修改默认函数行为
如果你想继续使用原生的get_previous_post()和get_next_post(),可以通过WordPress过滤器修改其查询逻辑,强制限制在当前子分类:
<?php global $wpdb; function restrict_prev_post_to_child_term($join) { global $post, $wpdb; // 仅针对Gallery自定义文章类型生效 if ($post->post_type !== 'gallery') return $join; $child_terms = wp_get_post_terms( $post->ID, 'category', array('fields' => 'ids', 'parent__not_in' => array(0)) ); if (empty($child_terms)) return $join; $target_term = $child_terms[0]; // 追加JOIN和WHERE条件,限制仅当前子分类 $join .= " INNER JOIN {$wpdb->term_relationships} AS tr ON p.ID = tr.object_id "; $join .= " INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id "; $join .= " WHERE tt.term_id = {$target_term} AND tt.taxonomy = 'category' "; return $join; } add_filter('get_previous_post_join', 'restrict_prev_post_to_child_term'); function restrict_next_post_to_child_term($join) { global $post, $wpdb; if ($post->post_type !== 'gallery') return $join; $child_terms = wp_get_post_terms( $post->ID, 'category', array('fields' => 'ids', 'parent__not_in' => array(0)) ); if (empty($child_terms)) return $join; $target_term = $child_terms[0]; $join .= " INNER JOIN {$wpdb->term_relationships} AS tr ON p.ID = tr.object_id "; $join .= " INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id "; $join .= " WHERE tt.term_id = {$target_term} AND tt.taxonomy = 'category' "; return $join; } add_filter('get_next_post_join', 'restrict_next_post_to_child_term'); ?>
将上述代码添加到主题的functions.php后,直接调用原函数即可:
<?php $prev_post = get_previous_post(true); $next_post = get_next_post(true); if ($prev_post) { echo '<a href="' . get_permalink($prev_post->ID) . '">上一篇:' . get_the_title($prev_post->ID) . '</a>'; } if ($next_post) { echo '<a href="' . get_permalink($next_post->ID) . '">下一篇:' . get_the_title($next_post->ID) . '</a>'; } ?>
注意事项
- 如果文章可能属于多个子分类,需要调整选取
$target_term_id的逻辑(比如根据当前页面的查询分类匹配,而非取第一个子分类)。 - 方案一中的
include_children => false确保不会包含当前子分类下的更深层级分类,若不需要可移除该参数。
内容的提问来源于stack exchange,提问作者Виталий Шпак
相关产品推荐
相关产品推荐

