已經多次有網友郵件提問,使用 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.