已經多次有網友郵件提問,使用 register_taxonomy 註冊了一個新的自定義分類法,比如 「products」,然後在後台創建了分類,想在前台將這些分類按層級列出,怎麼辦。

本篇教程就教大家實現 1. 按層級輸出分類。 2. 設置當前訪問項

當前訪問項

首先,按層級列出分類的時候,我們需要將當前訪問的分類加上特殊標記,比如"active"、"current"。

思路:需要考慮三種頁面, 1. 歸檔頁,2. 分類頁面,3. 文章頁。歸檔頁是沒有當前訪問項的,所以不需要考慮,分類頁面,不能簡單的獲取當前分類,若是在子分類頁面,還需將父分類也定義為正在訪問,文章頁,也是一樣,需要考慮父分類等。所以,正在訪問的項可能不止一個。

用圖來表示,可能更明瞭。

下面的代碼,將當前訪問項 (可能是多個) 放入數組 $current_array 中,要實現還需使用到一個阿樹自建的一個函數 ashuwp_get_top_term_id 。

  1. /**
  2. *獲取任意分類的"頂級父分類", 返回分類 ID, 若本身是頂級分類, 返回本身 ID
  3. * $term_id 分類的 ID
  4. * $taxonomy 分類法,默認為 category
  5. * $top_level 人為設定的頂級分類的父分類,默認為 0 。範例,若設置為 3,則將 ID 為 3 的分類的第一級子分類定義"頂級父分類"
  6. **/
  7. function ashuwp_get_top_term_id ($term_id ,$taxonomy='category', $top_level=0) {
  8.     while ($term_id != $top_level) {
  9.         $term = get_term($term_id$taxonomy);
  10.         $term_id = $term->parent;
  11.         $parent_id = $term->term_id;
  12.     }
  13.     return $parent_id;
  14. }
  15. /**先獲取當前頁面的分類 ID**/
  16. //分類頁面
  17. if(is_tax('products')){
  18.   $currentterm = get_queried_object(); //獲取當前分類
  19.   $currentterm_id = $currentterm->term_id;
  20.   //當前分類的頂級父分類 ID
  21.   $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
  22.   //獲取頂級分類對象
  23.   $top_term = get_term($top_term_id,'products');
  24.   //當前分類 ID 、當前分類的父分類 ID 都是當前訪問,放入 $current_array 數組
  25.   $current_array = array($currentterm_id);
  26.   $parent_id = $currentterm->parent;
  27.   while($parent_id){
  28.     $current_array[] = $parent_id;
  29.     $parent_term = get_term($parent_id, 'products');
  30.     $parent_id = $parent_term->parent;
  31.   }
  32. }elseif(is_singular('product')){
  33.   //單頁面
  34.   /*獲取文章所屬分類,文章同屬多個分類,將第一個分類當做 「當前分類」
  35.   *重複上面工作,將當前分類 ID 、當前分類的父分類 ID 都是當前訪問,放入 $current_array 數組
  36.   */
  37.   $terms = get_the_terms( $post->ID, 'products' );
  38.   if ( $terms && ! is_wp_error( $terms ) ) :
  39.     $currentterm = current($terms);
  40.     $current_array[] = $currentterm->term_id;
  41.     $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
  42.     $top_term = get_term($top_term_id,'products');
  43.     $parent_id = $currentterm->parent;
  44.     while($parent_id){
  45.       $current_array[] = $parent_id;
  46.       $parent_term = get_term($parent_id, 'products');
  47.       $parent_id = $parent_term->parent;
  48.     }
  49.   else:
  50.     $currentterm_id = 0;
  51.     $top_term_id = 0;
  52.     $current_array = array();
  53.   endif;
  54. }else{
  55.   //若為歸檔頁面,則沒有當前訪問
  56.   $currentterm_id = 0;
  57.   $top_term_id = 0;
  58.   $current_array = array();
  59. }

 

按層級輸出

思路:學過任意一門變成語言的人應該都會這個思路,先獲取所有頂級分類,將頂級分類循環輸出,在循環內部再嵌套輸出子分類的子循環。

  1. //先獲取所有頂級分類
  2. $top_args = array(
  3.   'taxonomy'=>'products', //分類法名稱
  4.   'hide_empty'=>false,
  5.   'parent'=>0, //頂級分類的父級都是 0
  6. );
  7. $top_terms = get_terms($top_args);
  8. if ( $top_terms && ! is_wp_error( $top_terms ) ) :
  9.   echo '<ul class="top_ul">'; //最外層 ul 標籤
  10.   //頂級分類循環輸出
  11.   foreach$top_terms as $top_term ):
  12.     $current = '';
  13.     //若這個頂級分類的 ID 在數組 $current_array 中,為當前訪問項
  14.     if(in_array($top_term->term_id,$current_array))
  15.       $current = 'class="current"';
  16.   ?>
  17.     <li <?php echo $current; ?>>
  18.       <a href="<?php echo get_term_link($top_term,'products'); ?>"><?php echo $top_term->name; ?></a>
  19.       <?php
  20.       //獲取當前頂級分類的子分類
  21.       $child_args = array(
  22.         'taxonomy'=>'products',
  23.         'hide_empty'=>false,
  24.         'parent'=>$top_term->term_id,
  25.       );
  26.       $child_terms = get_terms($child_args);
  27.       if ( $child_terms && ! is_wp_error( $child_terms ) ) :
  28.         echo '<ul>'; //第二層 ul 標籤
  29.         //循環子分類
  30.         foreach($child_terms as $child_term):
  31.           $current = '';
  32.           //若這個子分類的 ID 在數組 $current_array 中,為當前訪問項
  33.           if(in_array($child_term->term_id,$current_array))
  34.             $current = 'class="current"';
  35.           ?>
  36.             <li <?php echo $current; ?>><a href="<?php echo get_term_link($child_term,'products'); ?>"><?php echo $child_term->name; ?></a></li>
  37.           <?php
  38.           endforeach;
  39.         echo '</ul>';
  40.       endif;
  41.       ?>
  42.     </li>
  43.   <?php
  44.   endforeach;
  45.   echo '</ul>';
  46. endif;

總結

本篇教程共寫了兩段代碼,如果你並不清楚如何應用,請往下看。

首先,將本教程用到的一個函數放在主題的 functions.php 文件中,如下。

  1. /**
  2. *獲取任意分類的"頂級父分類", 返回分類 ID, 若本身是頂級分類, 返回本身 ID
  3. * $term_id 分類的 ID
  4. * $taxonomy 分類法,默認為 category
  5. * $top_level 人為設定的頂級分類的父分類,默認為 0 。範例,若設置為 3,則將 ID 為 3 的分類的第一級子分類定義"頂級父分類"
  6. **/
  7. function ashuwp_get_top_term_id ($term_id ,$taxonomy='category', $top_level=0) {
  8.     while ($term_id != $top_level) {
  9.         $term = get_term($term_id$taxonomy);
  10.         $term_id = $term->parent;
  11.         $parent_id = $term->term_id;
  12.     }
  13.     return $parent_id;
  14. }

再將下面一整段代碼放在要輸出分類列表的地方。

  1. <?php
  2. //分類頁面
  3. if(is_tax('products')){
  4.   $currentterm = get_queried_object(); //獲取當前分類
  5.   $currentterm_id = $currentterm->term_id;
  6.   //當前分類的頂級父分類 ID
  7.   $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
  8.   //獲取頂級分類對象
  9.   $top_term = get_term($top_term_id,'products');
  10.   //當前分類 ID 、當前分類的父分類 ID 都是當前訪問,放入 $current_array 數組
  11.   $current_array = array($currentterm_id);
  12.   $parent_id = $currentterm->parent;
  13.   while($parent_id){
  14.     $current_array[] = $parent_id;
  15.     $parent_term = get_term($parent_id, 'products');
  16.     $parent_id = $parent_term->parent;
  17.   }
  18. }elseif(is_singular('product')){
  19.   //單頁面
  20.   /*獲取文章所屬分類,文章同屬多個分類,將第一個分類當做 「當前分類」
  21.   *重複上面工作,將當前分類 ID 、當前分類的父分類 ID 都是當前訪問,放入 $current_array 數組
  22.   */
  23.   $terms = get_the_terms( $post->ID, 'products' );
  24.   if ( $terms && ! is_wp_error( $terms ) ) :
  25.     $currentterm = current($terms);
  26.     $current_array[] = $currentterm->term_id;
  27.     $top_term_id = ashuwp_get_top_term_id($currentterm->term_id,'products');
  28.     $top_term = get_term($top_term_id,'products');
  29.     $parent_id = $currentterm->parent;
  30.     while($parent_id){
  31.       $current_array[] = $parent_id;
  32.       $parent_term = get_term($parent_id, 'products');
  33.       $parent_id = $parent_term->parent;
  34.     }
  35.   else:
  36.     $currentterm_id = 0;
  37.     $top_term_id = 0;
  38.     $current_array = array();
  39.   endif;
  40. }else{
  41.   //若為歸檔頁面,則沒有當前訪問
  42.   $currentterm_id = 0;
  43.   $top_term_id = 0;
  44.   $current_array = array();
  45. }
  46. //先獲取所有頂級分類
  47. $top_args = array(
  48.   'taxonomy'=>'products', //分類法名稱
  49.   'hide_empty'=>false,
  50.   'parent'=>0, //頂級分類的父級都是 0
  51. );
  52. $top_terms = get_terms($top_args);
  53. if ( $top_terms && ! is_wp_error( $top_terms ) ) :
  54.   echo '<ul class="top_ul">'; //最外層 ul 標籤
  55.   //頂級分類循環輸出
  56.   foreach$top_terms as $top_term ):
  57.     $current = '';
  58.     //若這個頂級分類的 ID 在數組 $current_array 中,為當前訪問項
  59.     if(in_array($top_term->term_id,$current_array))
  60.       $current = 'class="current"';
  61.   ?>
  62.     <li <?php echo $current; ?>>
  63.       <a href="<?php echo get_term_link($top_term,'products'); ?>"><?php echo $top_term->name; ?></a>
  64.       <?php
  65.       //獲取當前頂級分類的子分類
  66.       $child_args = array(
  67.         'taxonomy'=>'products',
  68.         'hide_empty'=>false,
  69.         'parent'=>$top_term->term_id,
  70.       );
  71.       $child_terms = get_terms($child_args);
  72.       if ( $child_terms && ! is_wp_error( $child_terms ) ) :
  73.         echo '<ul>'; //第二層 ul 標籤
  74.         //循環子分類
  75.         foreach($child_terms as $child_term):
  76.           $current = '';
  77.           //若這個子分類的 ID 在數組 $current_array 中,為當前訪問項
  78.           if(in_array($child_term->term_id,$current_array))
  79.             $current = 'class="current"';
  80.           ?>
  81.             <li <?php echo $current; ?>><a href="<?php echo get_term_link($child_term,'products'); ?>"><?php echo $child_term->name; ?></a></li>
  82.           <?php
  83.           endforeach;
  84.         echo '</ul>';
  85.       endif;
  86.       ?>
  87.     </li>
  88.   <?php
  89.   endforeach;
  90.   echo '</ul>';
  91. endif;
  92. ?>

The end.