已经多次有网友邮件提问,使用 register_taxonomy 注册了一个新的自定义分类法,比如 「products」,然后在后台创建了分类,想在前台将这些分类按层级列出,怎么办。
本篇教程就教大家实现 1. 按层级输出分类。 2. 设置当前访问项
当前访问项
首先,按层级列出分类的时候,我们需要将当前访问的分类加上特殊标记,比如"active"、"current"。
思路:需要考虑三种页面, 1. 归档页,2. 分类页面,3. 文章页。归档页是没有当前访问项的,所以不需要考虑,分类页面,不能简单的获取当前分类,若是在子分类页面,还需将父分类也定义为正在访问,文章页,也是一样,需要考虑父分类等。所以,正在访问的项可能不止一个。
用图来表示,可能更明了。
下面的代码,将当前访问项 (可能是多个) 放入数组 $current_array 中,要实现还需使用到一个阿树自建的一个函数 ashuwp_get_top_term_id 。
- /**
- *获取任意分类的"顶级父分类", 返回分类 ID, 若本身是顶级分类, 返回本身 ID
- * $term_id 分类的 ID
- * $taxonomy 分类法,默认为 category
- * $top_level 人为设定的顶级分类的父分类,默认为 0 。范例,若设置为 3,则将 ID 为 3 的分类的第一级子分类定义"顶级父分类"
- **/
- function ashuwp_get_top_term_id ($term_id ,$taxonomy='category', $top_level=0) {
- while ($term_id != $top_level) {
- $term = get_term($term_id, $taxonomy);
- $term_id = $term->parent;
- $parent_id = $term->term_id;
- }
- return $parent_id;
- }
- /**先获取当前页面的分类 ID**/
- //分类页面
- if(is_tax('products')){
- $currentterm = get_queried_object(); //获取当前分类
- $currentterm_id = $currentterm->term_id;
- //当前分类的顶级父分类 ID
- $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
- //获取顶级分类对象
- $top_term = get_term($top_term_id,'products');
- //当前分类 ID 、当前分类的父分类 ID 都是当前访问,放入 $current_array 数组
- $current_array = array($currentterm_id);
- $parent_id = $currentterm->parent;
- while($parent_id){
- $current_array[] = $parent_id;
- $parent_term = get_term($parent_id, 'products');
- $parent_id = $parent_term->parent;
- }
- }elseif(is_singular('product')){
- //单页面
- /*获取文章所属分类,文章同属多个分类,将第一个分类当做 「当前分类」
- *重复上面工作,将当前分类 ID 、当前分类的父分类 ID 都是当前访问,放入 $current_array 数组
- */
- $terms = get_the_terms( $post->ID, 'products' );
- if ( $terms && ! is_wp_error( $terms ) ) :
- $currentterm = current($terms);
- $current_array[] = $currentterm->term_id;
- $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
- $top_term = get_term($top_term_id,'products');
- $parent_id = $currentterm->parent;
- while($parent_id){
- $current_array[] = $parent_id;
- $parent_term = get_term($parent_id, 'products');
- $parent_id = $parent_term->parent;
- }
- else:
- $currentterm_id = 0;
- $top_term_id = 0;
- $current_array = array();
- endif;
- }else{
- //若为归档页面,则没有当前访问
- $currentterm_id = 0;
- $top_term_id = 0;
- $current_array = array();
- }
按层级输出
思路:学过任意一门变成语言的人应该都会这个思路,先获取所有顶级分类,将顶级分类循环输出,在循环内部再嵌套输出子分类的子循环。
- //先获取所有顶级分类
- $top_args = array(
- 'taxonomy'=>'products', //分类法名称
- 'hide_empty'=>false,
- 'parent'=>0, //顶级分类的父级都是 0
- );
- $top_terms = get_terms($top_args);
- if ( $top_terms && ! is_wp_error( $top_terms ) ) :
- echo '<ul class="top_ul">'; //最外层 ul 标签
- //顶级分类循环输出
- foreach( $top_terms as $top_term ):
- $current = '';
- //若这个顶级分类的 ID 在数组 $current_array 中,为当前访问项
- if(in_array($top_term->term_id,$current_array))
- $current = 'class="current"';
- ?>
- <li <?php echo $current; ?>>
- <a href="<?php echo get_term_link($top_term,'products'); ?>"><?php echo $top_term->name; ?></a>
- <?php
- //获取当前顶级分类的子分类
- $child_args = array(
- 'taxonomy'=>'products',
- 'hide_empty'=>false,
- 'parent'=>$top_term->term_id,
- );
- $child_terms = get_terms($child_args);
- if ( $child_terms && ! is_wp_error( $child_terms ) ) :
- echo '<ul>'; //第二层 ul 标签
- //循环子分类
- foreach($child_terms as $child_term):
- $current = '';
- //若这个子分类的 ID 在数组 $current_array 中,为当前访问项
- if(in_array($child_term->term_id,$current_array))
- $current = 'class="current"';
- ?>
- <li <?php echo $current; ?>><a href="<?php echo get_term_link($child_term,'products'); ?>"><?php echo $child_term->name; ?></a></li>
- <?php
- endforeach;
- echo '</ul>';
- endif;
- ?>
- </li>
- <?php
- endforeach;
- echo '</ul>';
- endif;
总结
本篇教程共写了两段代码,如果你并不清楚如何应用,请往下看。
首先,将本教程用到的一个函数放在主题的 functions.php 文件中,如下。
- /**
- *获取任意分类的"顶级父分类", 返回分类 ID, 若本身是顶级分类, 返回本身 ID
- * $term_id 分类的 ID
- * $taxonomy 分类法,默认为 category
- * $top_level 人为设定的顶级分类的父分类,默认为 0 。范例,若设置为 3,则将 ID 为 3 的分类的第一级子分类定义"顶级父分类"
- **/
- function ashuwp_get_top_term_id ($term_id ,$taxonomy='category', $top_level=0) {
- while ($term_id != $top_level) {
- $term = get_term($term_id, $taxonomy);
- $term_id = $term->parent;
- $parent_id = $term->term_id;
- }
- return $parent_id;
- }
再将下面一整段代码放在要输出分类列表的地方。
- <?php
- //分类页面
- if(is_tax('products')){
- $currentterm = get_queried_object(); //获取当前分类
- $currentterm_id = $currentterm->term_id;
- //当前分类的顶级父分类 ID
- $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
- //获取顶级分类对象
- $top_term = get_term($top_term_id,'products');
- //当前分类 ID 、当前分类的父分类 ID 都是当前访问,放入 $current_array 数组
- $current_array = array($currentterm_id);
- $parent_id = $currentterm->parent;
- while($parent_id){
- $current_array[] = $parent_id;
- $parent_term = get_term($parent_id, 'products');
- $parent_id = $parent_term->parent;
- }
- }elseif(is_singular('product')){
- //单页面
- /*获取文章所属分类,文章同属多个分类,将第一个分类当做 「当前分类」
- *重复上面工作,将当前分类 ID 、当前分类的父分类 ID 都是当前访问,放入 $current_array 数组
- */
- $terms = get_the_terms( $post->ID, 'products' );
- if ( $terms && ! is_wp_error( $terms ) ) :
- $currentterm = current($terms);
- $current_array[] = $currentterm->term_id;
- $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
- $top_term = get_term($top_term_id,'products');
- $parent_id = $currentterm->parent;
- while($parent_id){
- $current_array[] = $parent_id;
- $parent_term = get_term($parent_id, 'products');
- $parent_id = $parent_term->parent;
- }
- else:
- $currentterm_id = 0;
- $top_term_id = 0;
- $current_array = array();
- endif;
- }else{
- //若为归档页面,则没有当前访问
- $currentterm_id = 0;
- $top_term_id = 0;
- $current_array = array();
- }
- //先获取所有顶级分类
- $top_args = array(
- 'taxonomy'=>'products', //分类法名称
- 'hide_empty'=>false,
- 'parent'=>0, //顶级分类的父级都是 0
- );
- $top_terms = get_terms($top_args);
- if ( $top_terms && ! is_wp_error( $top_terms ) ) :
- echo '<ul class="top_ul">'; //最外层 ul 标签
- //顶级分类循环输出
- foreach( $top_terms as $top_term ):
- $current = '';
- //若这个顶级分类的 ID 在数组 $current_array 中,为当前访问项
- if(in_array($top_term->term_id,$current_array))
- $current = 'class="current"';
- ?>
- <li <?php echo $current; ?>>
- <a href="<?php echo get_term_link($top_term,'products'); ?>"><?php echo $top_term->name; ?></a>
- <?php
- //获取当前顶级分类的子分类
- $child_args = array(
- 'taxonomy'=>'products',
- 'hide_empty'=>false,
- 'parent'=>$top_term->term_id,
- );
- $child_terms = get_terms($child_args);
- if ( $child_terms && ! is_wp_error( $child_terms ) ) :
- echo '<ul>'; //第二层 ul 标签
- //循环子分类
- foreach($child_terms as $child_term):
- $current = '';
- //若这个子分类的 ID 在数组 $current_array 中,为当前访问项
- if(in_array($child_term->term_id,$current_array))
- $current = 'class="current"';
- ?>
- <li <?php echo $current; ?>><a href="<?php echo get_term_link($child_term,'products'); ?>"><?php echo $child_term->name; ?></a></li>
- <?php
- endforeach;
- echo '</ul>';
- endif;
- ?>
- </li>
- <?php
- endforeach;
- echo '</ul>';
- endif;
- ?>
The end.