這里說的WordPress分類存檔頁,其實就是我們說的分類文章列表頁,比如 WordPress開發(fā)。最近有人找倡萌開發(fā)了一個分類存檔頁子分類選擇功能,單純文字說的不太清楚,配合下面的圖片做說明吧。
功能說明
當訪問一級分類(頂級分類),比如下圖的【作文】,就顯示【作文】下的子分類列表:

當訪問二級分類,【作文】-【動物作文】時,顯示它的子分類,同時還保留和它同級的二級分類,同時高亮顯示【動物作文】:

當訪問三級分類,【作文】-【動物作文】-【小雞】時,顯示的分類列表和上面一樣,只不過將【動物作文】和【小雞】高亮顯示:

此外,對子分類做一個高度限制,分類過多就顯示一個【點擊查看更多】的功能。
功能實現(xiàn)
我們需要通過php代碼去獲取數(shù)據(jù),然后配合js實現(xiàn)一些交互,以及通過css美化一下。
php部分
先貼下代碼,代碼中重要的部分都有注釋說明:
if( !class_exists('WPKJ_Get_Terms_List') ) :
/**
* 獲取當前分類的子分類列表
*/
class WPKJ_Get_Terms_List{
function __construct()
{
add_action( 'wp_enqueue_scripts', array( $this, 'wpkj_enqueue_terms_list_scripts'), 10 );
}
public function wpkj_enqueue_terms_list_scripts(){
if( is_category() || is_tax() ) {
wp_enqueue_style( 'terms-list-style', get_template_directory_uri() . '/assets/css/terms-list.css', array(), filemtime(get_template_directory().'/assets/css/terms-list.css') );
wp_enqueue_script( 'terms_list', get_template_directory_uri() . '/assets/js/terms-list.js', array('jquery'), '', true );
}
}
public function wpkj_terms_list( $hide_empty = false ){
//如果不是分類或自定義分類頁面,不執(zhí)行
if( !is_category() && !is_tax() ) return;
//獲取當前查詢的對象
$object = get_queried_object();
//如果對象不存在,不執(zhí)行
if( !$object ) return;
$taxonomy = $object->taxonomy; //獲取分類法
$current_id = $object->term_id; //獲取分類id
if( $current_id ){
//設置一下內容緩沖
ob_start();
echo '<div class="wpkj-terms-list">';
//獲取當前分類對象
$current = get_term( $current_id, $taxonomy );
//獲取當前分類的父級分類
$parent_id = $current->parent;
if ( $parent_id ) { // 存在父級分類,說明非頂級分類
$parent = get_term( $parent_id, $taxonomy );
$grand_parent_id = $parent->parent;
if( $grand_parent_id ){ //有祖父類,顯示父級分類兄弟
$this->wpkj_get_term_children( $grand_parent_id, $parent_id, $taxonomy, $hide_empty, 'term-parents' );
}
//如果有父類,顯示同級分類
$this->wpkj_get_term_children( $parent_id, $current_id, $taxonomy, $hide_empty, 'term-brothers' );
//如果有子分類,顯示子分類
$this->wpkj_get_term_children( $current_id, false, $taxonomy, $hide_empty, 'term-children' );
} else { // 頂級分類時
//如果有子分類,顯示子分類
$this->wpkj_get_term_children( $current_id, false, $taxonomy, $hide_empty, 'term-children' );
}
echo '</div>';
//輸出緩沖內容并清除緩沖
echo $result = ob_get_clean();
}
}
/**
* 通過父級id獲取并輸入子分類數(shù)據(jù)
* $parent_id 為父級id
* $term_id 為當前分類id,用于對比循環(huán)中哪個是當前分類,添加特定的css類名來適配高亮樣式
*/
public function wpkj_get_term_children( $parent_id, $term_id = false, $taxonomy, $hide_empty, $class = '' ){
$args = array(
'taxonomy' => $taxonomy,
'hide_empty' => $hide_empty,
'child_of' => $parent_id,
'parent' => $parent_id, // child_of 和 parent 指定為同一個id,將只獲取一個級別的數(shù)據(jù)
);
$terms = get_terms( $args );
if( !is_wp_error( $terms ) ){
$html = '<ul class="terms-ul '.$class.'">';
foreach ( $terms as $term) {
$id = $term->term_id;
//如果是當前分類,就添加一個類名,用于適配高亮樣式
if( $term_id && $id === $term_id ){
$html .= '<li class="current"><a href="'. get_term_link( $id, $taxonomy ) .'">'. $term->name .'</a></li>';
} else {
$html .= '<li><a href="'. get_term_link( $id, $taxonomy ) .'">'. $term->name .'</a></li>';
}
}
$html .= '</ul>';
echo $html;
}
}
}
endif;
new WPKJ_Get_Terms_List();
封裝了一個簡單的類 WPKJ_Get_Terms_List,為避免可能在以后的項目中有名稱沖突,所以在外圍判斷一下是否存在同名的類。
在 WPKJ_Get_Terms_List 這個類中,除了構造方法以外,包含三個方法:
wpkj_enqueue_terms_list_scripts:用于引入功能所需的css和js文件。當前的設置是將css和js放在主題的 assets 對應的目錄中,如果你的文件放在不同的路徑,自己修改路徑。wpkj_terms_list:查詢和判斷當前分類的數(shù)據(jù),然后進行輸出。參數(shù)$hide_empty用來設定是否輸出不含文章的空分類,默認為false,即輸出,如果不需要輸出空分類,在調用時,設置為truewpkj_get_term_children:用來獲取指定分類id的子分類數(shù)據(jù),里面的前兩個參數(shù)在注釋中有說明,其余參數(shù)是為了傳遞一些必要的參數(shù)值。
這次開發(fā),沒有找到直接獲取同級分類兄弟的方法,所以只能轉變方式,先獲取到父級分類id,然后再獲取子分類。剛開始嘗試過 get_term_children() ,發(fā)現(xiàn)它會獲取所有子分類,包括子分類的子分類,實在是沒有辦法僅限定為下一級的子分類。
然后想到了 get_terms() ,它的所有參數(shù)繼承自 WP_Term_Query 類,里面有參數(shù) child_of ,如果僅僅設置這個參數(shù),會和 get_term_children() 一樣包含了子分類的子分類。然后在網(wǎng)上看到有朋友指出,還需要同時設置 parent 參數(shù)為同一個父級分類id,才能限制只顯示下一級子分類。
JS部分
為了實現(xiàn)“點擊查看更多”的功能,需要配合js代碼操作,以下就是 terms-list.js 文件的代碼:
jQuery(document).ready(function($) {
// 這部分是為了設置哪個部分列表才是顯示在下方的第二部分子分類,
// 以及做一些樣式設置,并限定在手機端對父分類列表隱藏
if( $(".term-parents").length>0 ){
var ulClass = ".wpkj-terms-list .term-brothers";
$(".wpkj-terms-list .term-parents li").css("background", "rgb(242,242,242)");
if ($(window).width() < 860) {
$(".wpkj-terms-list .term-parents").hide();
}
} else if( $(".term-children").length>0) {
var ulClass = ".wpkj-terms-list .term-children";
$(".wpkj-terms-list .term-brothers li").css("background", "rgb(242,242,242)");
if ($(window).width() < 860) {
$(".wpkj-terms-list .term-brothers").hide();
}
} else {
var ulClass = ".wpkj-terms-list .term-brothers";
}
// 子分類部分超過設置的高度 117px 就顯示“點擊查看更多”
$(ulClass).each(function () {
if ($(this).height() > 117) {
var moreHtm = '<span class="more-item js_more">點擊查看更多</span>';
$(moreHtm).appendTo($(this).parent());
$(this).css("height", "117px");
}
});
$(document).on("click", ".wpkj-terms-list > .js_more", function () {
$(this).prev(ulClass).css("height", "auto");
$(this).removeClass("js_more").addClass("js_less");
$(this).html('點擊隱藏更多');
});
$(document).on("click", ".wpkj-terms-list > .js_less", function () {
$(this).prev(ulClass).css("height", "117px");
$(this).removeClass("js_less").addClass("js_more");
$(this).html('點擊查看更多');
});
});
注意代碼中 23、26、35 三行的數(shù)字 117,是高度設置值,你可能需要根據(jù)你的需要,修改這個高度,超過這個高度就顯示“點擊查看更多”。
倡萌的js是比較弱的,所以邏輯可能有些復雜,見笑了。
CSS樣式
我們還需要為列表添加一些樣式,以下就是 terms-list.css 的代碼:
.wpkj-terms-list{
margin: 15px 0;
}
.wpkj-terms-list .terms-ul{
list-style: none;
border-top: 1px solid rgba(0,0,0,.04);
border-left: 1px solid rgba(0,0,0,.04);
padding: 0;
overflow-y: hidden;
}
.wpkj-terms-list .terms-ul li{
width: 16.66%;
display: inline-block;
border-right: 1px solid rgba(0,0,0,.04);
border-bottom: 1px solid rgba(0,0,0,.04);
text-align: center;
background: #fff;
}
.wpkj-terms-list .terms-ul li a{
padding: 0;
display: block;
line-height: 2;
color: #333;
}
.wpkj-terms-list .terms-ul li.current a{
color: #ff6700;
}
.wpkj-terms-list .more-item{
width: 100px;
margin: 10px auto;
display: block;
cursor: pointer;
color: #ff6700;
}
@media screen and (max-width:860px){
.wpkj-terms-list .terms-ul li{
width: 20%;
}
}
@media screen and (max-width:640px){
.wpkj-terms-list .terms-ul li{
width: 25%;
}
}
@media screen and (max-width:480px){
.wpkj-terms-list .terms-ul li{
width: 33.33%;
}
}
@media screen and (max-width:360px){
.wpkj-terms-list .terms-ul li{
width: 50%;
}
}
樣式不可能適配所有主題,需要大家根據(jù)自己的需要去調整。
使用方法
一般來說,我們只需要在分類列表的文件,比如 category.php 的適當位置添加下面的代碼即可:
<?php
if( class_exists('WPKJ_Get_Terms_List') ) {
$list = new WPKJ_Get_Terms_List();
$list->wpkj_terms_list(); // 如果需要隱藏空分類,在左邊的括號內填入 true
}
?>
先判斷是否存在我們的類,然后實例化并輸出。
從一開始,倡萌就考慮到兼容自定義分類法的,也就是說不僅僅可用于文章的分類,還可以是其他自定義文章類型的自定義分類法。你只需要將上面的代碼添加到自定義分類法的列表文件中即可。





沒明白怎么用的,PHP的內容是放在什么位置呢?
你可以放到你自己的開發(fā)的插件,或主題的functions.php。不過,從你的提問知道你應該不懂PHP開發(fā),所以這個文章可能不適合你
請問,有類似這種功能的插件么?我在嘗試將您的代碼封裝成插件。
客戶提供需求后,我尋找過插件,但是沒有發(fā)現(xiàn)可以滿足條件的
哈哈,我也是在尋找,實在找不到了。關鍵詞:過濾器、選擇器、菜單。
我把上面的代碼封裝成插件了,用短代碼的方式嵌入頁面,不過我那個站的一級目錄是自定義帖子的類型,爆出了一些錯誤,不懂插件開發(fā)的我還在嘗試解決中。
Notice: Undefined property: WP_Post_Type::$taxonomy in \wp-content\plugins\dd-category-filter\dd-category-filter.php on line 42 Notice: Undefined property: WP_Post_Type::$term_id in \wp-content\plugins\dd-category-filter\dd-category-filter.php on line 43