熟悉 WordPress Walker 課程

已發表: 2020-11-27

如果您不熟悉 Walker 課程,請準備好對它對您的工作的幫助感到驚訝。 WordPress Walker 類在 WordPress 2.1 中實現,為開發人員提供一種遍歷樹狀數據結構以呈現 HTML 的方法。 在本文中,我們將研究 walker 參數的工作原理以及如何自定義菜單、類別和評論中的輸出。

我們走吧!

沃克類概述

在 WordPress 中,我們經常看到具有層次結構的對象,例如導航菜單、類別列表或評論列表

您可能已經知道,在樹數據結構的情況下,一些元素是父元素,而另一些元素是它們的子元素。 “發布子類別 1”是“發布類別 1”的子項,對評論的回復是評論本身的子評論,“服務 1”是“服務”項的子菜單項。

Walker 被命名為它簡單地“遍歷”每個對像或關聯數組並在每個節點處執行一個函數。 我們想要實現的是能夠根據我們的具體要求以不同的方式列出“頂級”鏈接及其“子”項。

換句話說,WordPress 為您提供了一個標準的 <ul> <li> 結構,您可以自定義其參數,但是,通過擴展 Walker,您可以通過修改其 HTML 內容來自定義結構本身。

與 Walker 類相關的核心文件是wp-includes/class-wp-walker.php ,它管理著我們之前列出的所有類型的樹狀數據。

由於它是一個抽象的 PHP 類,為了生成任何 HTML,它必須由開發人員對其屬性和方法的自定義版本進行擴展。 那麼我們來一一研究class-wp-walker.php文件中的子類。

子班

$tree_type是一個可選變量,它以類型或類型數組的形式出現,並定義類處理的內容。

 public $tree_type = array( 'post_type', 'taxonomy', 'custom' );

$db_fields是必需的變量,它定義要使用的數據庫字段。 該屬性是一個具有兩個鍵的數組:“parent”和“id”,其值是分別保存父 id 和項 id 的對象屬性的名稱。

 public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id', );

$max_pages屬性也是可選的,它的作用是指定分頁步行者走過的最大頁面數。

 public $max_pages = 1;

$has_children實際上是不言自明的,它的真假值取決於當前元素是否有子元素。

 public $has_children;

start_lvl方法在新的樹狀對象的根上執行,並接受 $output、$depth 和 $args 參數。

 public function start_lvl( &$output, $depth = 0, $args = array() ) {}

$output參數附加附加內容, $depth指定項目的深度, $args是附加參數的數組。

end_lvl方法關閉之前由 start_lvl 方法打開的任何標籤。

 public function end_lvl( &$output, $depth = 0, $args = array() ) {}

start_el (起始元素)方法用於顯示當前元素的開始 HTML 標記。 例如,在菜單的情況下,它通常是一個 <li> 標籤。

 public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {}

在 Walker 傳遞一個元素及其所有子元素並返回一個結束標記後,調用end_el函數。

 public function end_el( &$output, $object, $depth = 0, $args = array() ) {}

display_element實際上顯示了樹對象的元素。 它按此順序調用start_elstart_lvldisplay_elementend_lvlend_el函數。 現在讓我們來看看它的論點。

  • $element : 當前元素
  • $children_elements : 樹對象的所有子元素
  • $max_depth :我們可以探索的最大深度限制
  • $depth :我們目前所處的水平
  • $args : 額外的可選參數
  • $output :當前的 HTML 輸出。

現在,我們將使用激活二十二十主題的 WordPress 安裝來演示每種數據類型的一個示例。

自定義菜單結構

WordPress 用於顯示菜單的 wp_nav_menu() 函數包含在wp-includes/nav-menu-template.php文件中。 在這個文件中,WordPress 還在第 605 行調用了 Walker_Nav_Menu 類。

 function walk_nav_menu_tree( $items, $depth, $r ) { $walker = ( empty( $r->walker ) ) ? new Walker_Nav_Menu : $r->walker; return $walker->walk( $items, $depth, $r ); }

Walker_Nav_Menu類在wp-includes/class-walker-nav-menu.php文件中定義,它基本上是文件的所有內容。

為了顯示菜單的輸出,WordPress 代碼使用了該文件中描述的 Walker_Nav_Menu 類的屬性和方法。

例如,讓我們解決許多開發人員面臨的一個眾所周知的問題,即使用空的自定義鏈接 ('#') 更改父菜單項的元素,以防止訪問者單擊它們。

為了使我們能夠比較我們的結果,我們將首先通過在<header>元素開始後的header.php中添加以下代碼來創建主菜單的克隆。

 <header class="header-footer-group" role="banner"> <?php wp_nav_menu( array( 'menu_class' => 'primary-menu reset-list-style' ) ); ?>

我們實際上在這裡所做的是重新生成主菜單並通過將其類primary-menu reset-list-style也添加到新菜單來繼承其下拉功能和 CSS。

現在在我們的functions.php文件中,我們將創建一個擴展Walker_Nav_Menu 類的類。 由於我們要更改元素的類型,我們將覆蓋start_el方法。

 if ( !class_exists('My_Custom_Nav_Walker') ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth=0, $args=[], $id=0) { $output .= "<li class='" . implode(" ", $item->classes) . "'>"; if ($item->url && $item->url != '#') { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ($item->url && $item->url != '#') { $output .= '</a>'; } else { $output .= '</span>'; } } } }

因此,我們通常用 <li> 標記包裝每個元素,然後使用 if 語句在鏈接為“#”時附加一個 span,其餘部分使用 <a> 標記。

要將它應用到我們的菜單,我們回到我們之前添加的菜單代碼並指定 walker 參數:

 wp_nav_menu( array( 'walker' => new My_Custom_Nav_Walker, 'menu_class' => 'primary-menu reset-list-style' ) );

現在結果應該是這樣的:

如果您現在將鼠標懸停在菜單項中的“服務”上,則不會出現手形光標,並且該菜單項也不能單擊。 但是,下拉子菜單仍將正確顯示。

自定義類別

首先進入管理區域並創建一些帖子類別和子類別,以便有一個用於演示的類別樹。

之後,我們將通過在header.php中的某處添加此代碼來生成類別列表。 您可以像以前一樣將它放在標題元素的開頭之後。

 <header class="header-footer-group" role="banner"> <?php wp_list_categories( array('hide_empty' => FALSE) ); ?>

該函數是一個內置的 WordPress 函數,可生成類別樹的 HTML 輸出。 默認情況下,它只顯示包含帖子的類別,這就是我們使用hide_empty選項來顯示空類別並查看整個層次結構的原因。

如前所述,我們可以在functions.php中創建一個自定義類來擴展wp-includes/class-walker-category.php文件中描述的默認 Walker_Category 類並應用我們的更改。 例如,我們將通過添加以下代碼在類別名稱前添加一些圖標:

 if ( !class_exists('My_Category_tree_Walker') ) { class My_Category_tree_Walker extends Walker_Category { function start_el(&$output, $item, $depth=0, $args=array(),$current_object_id = 0) { $output.= '<li><a href="'.home_url('category/'.$item->slug).'"> <img src="http://path/to/mages/'.($item->slug).'.jpg"> '.esc_attr($item->name); } } }

為此,您當然需要準備合適的圖像並將它們保存在定義的文件夾中。 這些圖像需要遵循特定的名稱格式,在本例中為“post-category-1”、“post-subcategory-1”、“post-category-3.jpg”等。

自定義評論

更新菜單和類別列表是迄今為止您可能自定義 Walker 類的最常見原因,但有時您也必須為評論實現相同的技術。 例如,如果您想更改評論部分中 Gravatar 圖像旁邊的元信息,我們可以通過擴展 wp-includes/class-walker-comment.php 文件中的 Walker_Comment 類輕鬆做到這一點。

在 functions.php 文件中添加此代碼

if ( !class_exists('My_Comment_Walker') ) { class My_Comment_Walker extends Walker_Comment { protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> <<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> <article class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?> <?php printf( __( '%s <span class="says">says:</span>' ), sprintf( '<span class="fn">%s</span>', get_comment_author_link( $comment ) ) ); ?> </div><!-- .comment-author --> <div class="comment-metadata"> <?php $user_id=$comment->user_id; ?> <p class="commenter-bio"><?php the_author_meta('description',$user_id); ?></p> <p class="commenter-url"><a href="<?php the_author_meta('user_url',$user_id); ?>" target="_blank"><?php the_author_meta('user_url',$user_id); ?></a></p> </div><!-- .comment-metadata --> <?php if ( '0' == $comment->comment_approved ) : ?> <p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></p> <?php endif; ?> </footer><!-- .comment-meta --> <div class="comment-content"> <?php comment_text(); ?> </div><!-- .comment-content --> <?php comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="reply">', 'after' => '</div>' ) ) ); ?> </article><!-- .comment-body --> <?php } } }

您可以通過將 about 代碼與原始 Walker_Comment 的內容進行比較注意到,唯一需要更改的是html5_comment方法,該方法基本上以 HTML5 格式輸出註釋。

之後,我們必須使用帶有正確參數的內置 wp_list_comments 函數來顯示評論列表,以顯示評論樹狀對象 HTML。

 wp_list_comments( array( 'page' => 143, 'walker' => new My_Comment_Walker ));

我們將代碼插入到我們之前所做的同一行 header.php 中,並使用包含評論的帖子的 ID。 當然,您可以簡單地替換模板的評論相關代碼並跳過“頁面”選項,以便它適用於您的所有文章評論部分。

如果您現在刷新您的網站前端,您會注意到我們在上面的自定義代碼中添加的額外信息條目(作者簡介和作者 URL)。

結論

希望以上內容讓您對使用 WordPress Walker 類有所了解。 在所有示例中,我們將更改直接應用於核心主題文件。 雖然這對於演示目的來說很好,但您顯然希望確保在實踐中只對子主題應用編輯,以確保在更新 WordPress 或使用的主題時不會覆蓋這些更新。