WordPress鉤子(Hook)是WordPress開發人員的武器庫中最重要的工具之一。它們是WordPress外掛和主題開發的基礎。您可以使用WordPress的許多內建鉤子將自定義程式碼“連線到”WordPress核心,並執行或修改某些內容。
有兩種型別的WordPress鉤子:Actions和Filters。Hook非常普遍,甚至WordPress Core本身也廣泛使用它們。WordPress還提供了一種讓您定義自己的自定義鉤子的方法,以便其他開發人員可以掛鉤到您的程式碼中。
瞭解動作、過濾器和自定義鉤子的工作原理對於掌握WordPress開發至關重要。
本文的前半部分介紹了WordPress鉤子的基礎知識,並解釋了它們如何與多個示例一起工作。在後半部分,您將學習如何使用鉤子來自定義WordPress,建立自己的自定義鉤子,並使用它們來構建自己的可擴充套件外掛。
- 什麼是WordPress鉤子?
- 鉤子 vs 動作 vs 過濾器
- WordPress鉤子如何工作?
- 在哪裡註冊鉤子及其函式?
- 使用WordPress鉤子
- WordPress鉤子列表和資源
- 查詢在WordPress頁面上註冊的鉤子
- “所有”鉤子
- WordPress鉤子儲存在哪裡?
- 如何建立自定義WordPress鉤子
- 從WordPress鉤子中刪除回撥函式
- 更多WordPress鉤子教程
什麼是WordPress鉤子?
一個WordPress的頁面是由很多的功能和資料庫查詢組裝。WordPress核心、外掛和主題協同工作以輸出頁面元素,如文字、影象、指令碼和樣式。完全組裝後,瀏覽器會將它們放在一起並呈現頁面。
WordPress鉤子允許您在某些點“鉤入”這個構建過程並執行您的自定義程式碼。鉤子的主要功能是讓你在不接觸核心檔案的情況下修改或新增功能到WordPress 。
鉤子將幫助您使用自己的程式碼擴充套件WordPress
在WordPress的外掛API賦予WordPress鉤子的功能。您可以通過在WordPress執行時在特定例項中呼叫某些稱為Hook Functions的WordPress函式來使用鉤子。
使用鉤子函式,您可以將自定義程式碼捆綁在回撥函式中,並將其註冊到任何鉤子中。註冊後,此回撥將在鉤子所在的任何地方執行,允許您增加或替換預設的WordPress功能。
鉤子在程式碼執行過程中的位置是一個重要的因素。您將在接下來的部分中詳細瞭解其重要性。
兩種型別的WordPress鉤子:動作和過濾器
WordPress包括兩種型別的鉤子,稱為Actions和Filters。動作允許您在WordPress執行時的某些預定義點執行某些操作,而過濾器允許您修改WordPress處理的任何資料並返回這些資料。
動作(Actions)在WordPress程式碼中定義為:
do_action( 'action_name', [optional_arguments] );
action_name
字串是動作的名稱。您可以指定[optional_arguments]
變數以將附加引數傳遞給回撥函式。如果未指定此欄位,則其預設值將為空。
示例:do_action( 'wp_head' )
每次WordPress處理站點標題時,都可以掛接該動作以執行自定義程式碼。此動作沒有任何其他引數。
過濾器(Filters)在WordPress程式碼中定義為:
apply_filters( 'filter_name', 'value_to_be_filtered', [optional_arguments] );
filter_name
是過濾器的名稱,value_to_be_filtered
是可以被過濾器函式修改的值,[optional_arguments]
可選,若干個可以傳遞給過濾器函式的引數。
例如:apply_filters( 'admin_footer_text' , string $text )
這個過濾器可以用來修改管理頁尾顯示的文字。從WordPress 5.4開始,其預設在管理區域頁尾中顯示該句子:Thank you for creating with WordPress.
稍後您將通過WordPress核心中的許多示例來學習如何使用動作和過濾器鉤子,這將有助您通過程式碼在網站上執行或自定義某些內容。例如,您可以使用鉤子在釋出文章後自動傳送電子郵件,或載入自定義樣式表來更改站點的外觀。
WordPress鉤子可幫助您與網站互動或修改您的網站
為更好理解Wordpress鉤子, 可將您的WordPress網站想象成蓋房子。鉤子類似於使用起重機來回移動建築物品,在傳輸的專案是回撥函式,其中包括您的自定義程式碼。這些專案(或功能)可以幫助您建造或改造房屋。
在WordPress中“wp_head”動作鉤子的示例
回撥函式可以是常規PHP函式、預設WordPress函式或您定義的自定義函式。
我們只能在連線到特定掛鉤的特定載體上運輸某些物品。因此,動作只能與動作函式掛鉤。同樣,過濾器只能與過濾器函式掛鉤。
雖然更換起重機上的吊鉤和托架很乏味,但WordPress通過包含超過2,200種預設鉤子使其變得非常容易。
WordPress 5.1有2200多個原生鉤子(來源:Adam Brown)
您可以發現WordPress核心流程遍佈有鉤子,讓您可以方便地鉤子的確切位置執行您的自定義程式碼。
鉤子(Hook) vs 動作(Action) vs 過濾器(Filter)
鉤子(Hook)是以一段程式碼互動/修改另一段程式碼的一種方式……
鉤子(Hook)包括兩種型別:動作(Action)和過濾器(Filter)。
一些教程和指南將Hook、Action和Filter的使用方式與之相關的函式混合在一起介紹,讓初學者誤以為它們之間存在廣泛的不一致。但您仔細檢視WordPress核心程式碼,您會發現新增動作和過濾器之間其實沒有太大區別。
下面是wp-includes/plugin.php
檔案中為ADD_ACTION()函式的原始碼:
function add_action( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { return add_filter( $tag, $function_to_add, $priority, $accepted_args ); }
可留意到add_action()
函式其實只是呼叫該add_filter()
函式並返回其值。為什麼?因為從根本上它們幾乎以相同的方式工作,除了一個區別:apply_filters()
函式返回一個可以更改現有資料的值,而該do_action()
函式不返回任何內容(PHP中的NULL值)。
如果您仍然感到困惑,請不要擔心!讀完本文的前半部分後,一切就都清楚了。
我們將堅持使用官方清晰、準確且通用的WordPress Codex術語來幫助你理解。現在請先熟悉下面顯示的鉤子示意圖:
鉤子程式:鉤子、鉤子函式和回撥函式
讓我們分解一下Actions和Filters之間的區別。
WordPress鉤子 (Hook) | |
動作 (Actions) | 過濾器 (Filter) |
動作用於在WordPress Core執行期間的特定點執行自定義函式。 | 過濾器用於修改或自定義其他功能使用的資料。 |
動作由do_action( ‘action_name’ ) WordPress程式碼中的函式定義/建立。 |
過濾器由apply_filters( ‘filter_name’, ‘value_to_be_filtered’ ) WordPress程式碼中的函式定義/建立。 |
動作也稱為動作鉤子。 | 過濾器也稱為過濾器鉤子。 |
動作只能與動作函式掛鉤。例如add_action() ,remove_action() 。 |
過濾器只能與過濾器函式掛鉤。例如add_filter() ,remove_filter() 。 |
動作函式不需要向它們的回撥函式傳遞任何引數。 | 過濾器函式需要至少傳遞一個引數給它們的回撥函式。 |
動作函式可以執行任何型別的任務,包括改變WordPress工作方式的行為。 | 過濾器函式僅用於修改過濾器傳遞給它們的資料。 |
動作函式應該不return 什麼。但是,它們可以echo 輸出或與資料庫互動。 |
過濾器函式必須最有return 動作,即使過濾器函式什麼都不改變,它仍然必須將未修改的資料重新return 。 |
只要程式碼有效,動作幾乎可以執行任何操作。 | 過濾器應該以孤立的方式工作,因此它們不會產生任何意外的副作用。 |
總結:一個動作會中斷常規的程式碼執行過程,用它接收到的資訊做一些事情,但什麼都不返回,然後退出。 | 總結:過濾器修改它接收到的資訊,將其返回給呼叫鉤子函式,其他函式可以使用它返回的值。 |
有時,您可以使用動作或過濾器來實現相同的目標。例如,如果您想修改文章中的文字,您可以使用publish_post動作註冊一個回撥函式,並在將文章內容儲存到資料庫時更改文章內容。
// define the callback function to change the text function change_text_callback() { // add the code to change text here } // hook in to the 'publish_post' action with the add_action() function add_action( 'publish_post', 'change_text_callback' );
或者您可以使用the_content過濾器註冊另一個回撥函式,以在瀏覽器中顯示之前修改文章內容。
// define the callback function to modify the text function change_text_another_callback( $content ) { // add the code to change text here and then return it return $filtered_content; } // hook in to 'the_content' filter with the add_filter() function add_filter( 'the_content', 'change_text_another_callback');
兩種不同的方法,結果相同。知道何時使用那個而不是另一個是成為優秀WordPress開發人員的關鍵。
WordPress鉤子如何工作?
通過房子的例子可很簡單理解鉤子的基本功能,但它沒有捕捉到它們如何工作的複雜性。而最關鍵的是放置鉤子的位置和特異性的概念。
一個更好的例子是將處理WordPress網頁想象成組裝汽車。與製造汽車需要時間不同,組裝網頁幾乎是瞬間完成的。
組裝網頁就像組裝汽車
就像汽車如何在現代裝配線中逐個組裝在一起一樣,WordPress網頁由伺服器和客戶端逐個組裝。WordPress核心就像汽車引擎、底盤和其他必需品,為網站的“核心”功能提供動力。您可以僅使用WordPress核心就擁有一個功能強大的網站,但這有什麼樂趣呢?您需要向站點新增令人興奮的功能。這就是WordPress外掛和主題介入的地方,它們都廣泛使用鉤子。
在上面的示例中,每個編號的站點就像WordPress核心中的一個鉤子。有兩種型別的站點,例如動作和過濾器。每個站都包含一個特定型別的插槽,它只接受某些工具,類似於動作函式和過濾器函式。為了模組化和效率,所有站點都以頻繁的間隔放置。
根據特定位置的要求,我們可以為該特定站點的工作安裝(或鉤子)最合適的工具。這些工具就像用於與WordPress互動或修改WordPress的回撥函式。一些工具可以顯著改變汽車的工作,註冊到動作鉤子的回撥如同其一樣;而其他工具僅用於自定義汽車的外觀,註冊到過濾器的回撥對應類比如此。在正確的站點使用正確的工具對於製造一流的汽車至關重要。同樣,鉤子能幫助我們滿足獨特需求來實現定製WordPress。
如果你擴充套件這個類比,可以是:外掛就像新增有用的汽車功能,如安全氣囊、娛樂控制檯、遠端無鑰匙系統等(像這些是為了增強WooCommerce的功能);主題類似於自定義汽車的視覺部分,如整體設計、噴漆、輪輞等(這是自定義WordPress主題的方法)。
在哪裡註冊鉤子及其函式?
在WordPress中新增鉤子有兩種推薦的方法:
- 外掛:製作您自己的外掛並在其中新增所有自定義程式碼。
- 主題:在子主題的
functions.php
檔案中註冊鉤子和回撥函式。
接下來讓我們從建立外掛開始來說明具體方法細節。
首先,請在您的/wp-content/plugins/
目錄中建立一個新資料夾。我給我的外掛命名salhooks
,當然你可以隨意命名它。根據 WordPress 指南,您需要在外掛目錄中建立一個具有相同名稱 (salhooks.php
)的PHP檔案。
將以下標題欄位新增到您的外掛檔案以將其註冊到WordPress。您可以在WordPress Codex中瞭解有關外掛標頭要求的更多資訊。
<?php /* Plugin Name: Salhooks Version : 1.0 Description: Demonstrating WordPress Hooks (Actions and Filters) with multiple examples. Author : Salman Ravoof Author URI : https://www.salmanravoof.com/ License : GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Text Domain: salhooks */ //================================================= // Security: Abort if this file is called directly //================================================= if ( !defined('ABSPATH') ) { die; }
儲存此檔案,然後在您的WordPress儀表盤中啟用該外掛。我將在最新版本WordPress本地環境搭建與安裝教程中使用這個外掛來演示鉤子是如何工作的。
作為旁註,您可以直接編輯WordPress核心檔案以註冊鉤子。但是,不建議這樣做,因為每次更新WordPress時,您的所有自定義程式碼都會被覆蓋。出於同樣的原因,如果您使用的是某個子主題,您不應該在其對應的父主題中新增鉤子。
使用WordPress鉤子
一個WordPress鉤子本身什麼都不做。它只是置於程式碼中,等待一些鉤子函式來啟用它。要使用鉤子,您至少需要呼叫2個其他函式。
首先,您需要使用鉤子函式註冊鉤子並在其中引用回撥函式。然後你需要定義你之前在鉤子函式中提到的回撥函式。每次觸發鉤子時,WordPress都會執行此回撥函式。定義這些函式的順序無關緊要,但最好將它們放在一起。
動作和過濾器具有不同的鉤子函式。從現在開始,讓我們將它們稱為Action Functions和Filter Functions。正如您將看到的,它們有自己的語法和引數要求。
鉤住一個動作
動作(action)提供了一種在WordPress 核心、外掛或主題執行中的特定點執行自定義程式碼的方法。
add_action() 動作函式
您可以按照以下步驟使用動作註冊回撥函式:
- 定義一個帶有自定義程式碼的回撥函式。當WordPress的程式碼執行期間觸發它註冊到的任何動作時,此回撥函式將執行。
- 使用該
add_action()
函式將您的回撥函式連線到您想要的動作。參照WordPress Codex說明,add_action()函式至少需要傳遞兩個引數:-
- 要掛鉤的動作的名稱。
- 觸發動作時將執行的回撥函式的名稱。
-
add_action()
函式還接受兩個可選引數來設定priority
(執行優先順序次序) 和number of arguments
(引數數量),我們稍後會討論它們。
最好將回撥函式引數命名為儘可能接近鉤子函式傳遞的引數。
讓我們看一個使用該add_action()
函式的例子。
// define the callback function, the arguments are optional function example_callback( $arg1, $arg2 ) { // make your code do something with the arguments } // hook the callback function to the 'example_action' add_action( 'example_action', 'example_callback', [priority], [no_of_args] ); // 'priority' and 'number of arguments' are optional parameters
掛鉤動作的示例
WordPress包含一個名為init的內建動作,它會在WordPress完成載入並驗證使用者之後,但在傳送任何標頭之前觸發。許多外掛使用此鉤子作為例項化其程式碼的起點,因為在WordPress執行此動作時,幾乎所有主要的WordPress功能都已完成載入。
WordPress有一個類似的動作叫做admin_init。它在初始化管理介面時init
觸發,而動作僅在WordPress完成載入後觸發。
讓我們實現在init
動作執行期間執行一個自定義程式碼來echo
一條簡單的訊息。程式碼如下:
function custom_callback_function(){ // add your custom code here to do something echo 'I will be fired on WordPress initialization'; } add_action( 'init', 'custom_callback_function' );
您可以在我最新版本WordPress本地環境搭建與安裝教程的提及的例項的頁面左上角看到這條訊息。
不是很漂亮,但這是一個很好的開始!
查詢WordPress支援的動作
WordPress每次執行某些動作時都會包含一些動作鉤子,例如使用者登入或釋出新文章。您可以在外掛API/動作參考頁面中找到WordPress執行的所有動作的完整參考列表。
幾乎每次使用都有一個動作
Codex將其中列出的所有動作分為不同的類別,並按照WordPress執行順序從頭到尾排列。
在大多數情況下,許多這些動作不會做任何事情,因為沒有任何東西與它們掛鉤。但是,如果您需要它們,它們就在那裡供您使用。
對所有的動作感到有點不知所措?這是自然的。隨著您獲得更多經驗並瀏覽WordPress核心原始碼,找到滿足您需求的完美鉤子將變得更加容易。只需搜尋術語“ do_action ”,您就會發現許多可以鉤子的動作。
add_action() 的附加引數
add_action()
函式可以接受另外兩個引數:一個用於設定priority
,另一個用於設定number of arguments
。雖然它們是可選的,但如果使用得當,它們會非常有用。
優先事項
函式支援的第一個附加引數add_action()
設定priority
. 該引數只能是正整數。優先順序數字越低,函式執行得越早。如果不指定,其預設值為10。
為了看看它是如何工作的,讓我們為init
動作註冊三個回撥函式,但每個都有不同的優先順序。
// priority is set to 9, which is lower than 10, hence it ranks higher add_action( 'init', 'i_am_high_priority', 9 ); // if no priority is set, the default value of 10 will be used add_action( 'init', 'i_am_default_priority'); // priority is set to 11, which is higher than 11, hence it ranks lower add_action( 'init', 'i_am_low_priority', 11 );
在上面的示例中,優先順序編號最低的回撥函式將首先執行,編號最高的回撥函式將最後執行。如果它們的優先順序相同,那麼它們將按照您註冊它們的先後順序執行。
當單個鉤子可以註冊多個回撥函式時,優先順序起著重要作用。為避免意外結果,您可以為每個回撥函式設定優先順序,以便它們按您希望的順序觸發。
引數數量
預設情況下,通過該函式註冊的任何回撥函式add_action()
將只接收一個引數。但是,有時您可能需要向回撥函式傳遞額外的資料。出於這個原因,add_action()
函式接受一個可選引數來設定引數的數量。
展示這一點的一個很好的例子是comment_post動作。此動作會在WordPress向資料庫新增評論後立即執行。如果您不設定number of arguments
引數,它只會將一個值傳遞給回撥函式,在這種情況下將是comment_ID
.
// register the hook with 'priority' and 'number of arguments' parameters add_action( 'comment_post', 'show_message_function', 10, 3 ); // define the callback function function show_message_function( $comment_ID, $comment_approved, $commentdata ) { // check whether a comment is approved with the second parameter if( 1 === $comment_approved ){ // runs the code only if the comment is approved } }
如果如上例所示將引數number of arguments設定為3,則動作函式將傳遞三個值:comment_ID
、comment_approved
和commentdata
。
WordPress將comment_approved
的值設定為1,如果未批准,則設定為0,如果評論標記為垃圾評論,則設定為“spam”。
commentdata
變數是一個包含所有評論資料的陣列,例如評論作者的姓名、電子郵件地址、網站和評論本身的內容。您可以檢視WordPress Codex以查詢包含在 ‘commentdata’ 陣列中的所有鍵值對。
您可以擁有任意數量的引數,但回撥函式和add_action()
函式需要指定相同數量的引數。
通過將附加引數傳遞給回撥函式,您可以對程式碼執行更多動作。例如,您可以檢查評論是否獲得批准,並在獲得批准後自動將評論文字通過電子郵件傳送給管理員。不指定附加引數就不可能做到這一點,因為您的回撥函式將無法訪問comment_content
資料。
如果不想設定優先順序,只想改變引數個數,還是需要設定一個優先順序。只需使用其預設值(即 10)。
WordPress核心如何使用動作鉤子
WordPress Core本身使用許多內建動作來執行各種功能。
以wp_head動作為例。當WordPress輸出網頁的標題部分(在<head>
和之間的程式碼)時,它會被觸發</head>
。
你可以在wp includes/default-filters.php
檔案中找到大多數與wp_head
鉤子相關的WordPress核心動作函式。我仔細檢視了程式碼並編譯了所有呼叫wp_head
動作的add_action()
函式的列表。
add_action( 'wp_head', 'rest_output_link_wp_head', 10, 0 ); add_action( 'wp_head', '_wp_render_title_tag', 1 ); add_action( 'wp_head', 'wp_enqueue_scripts', 1 ); add_action( 'wp_head', 'wp_resource_hints', 2 ); add_action( 'wp_head', 'feed_links', 2 ); add_action( 'wp_head', 'feed_links_extra', 3 ); add_action( 'wp_head', 'rsd_link' ); add_action( 'wp_head', 'wlwmanifest_link' ); add_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 ); add_action( 'wp_head', 'locale_stylesheet' ); add_action( 'wp_head', 'noindex', 1 ); add_action( 'wp_head', 'print_emoji_detection_script', 7 ); add_action( 'wp_head', 'wp_print_styles', 8 ); add_action( 'wp_head', 'wp_print_head_scripts', 9 ); add_action( 'wp_head', 'wp_generator' ); add_action( 'wp_head', 'rel_canonical' ); add_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 ); add_action( 'wp_head', 'wp_custom_css_cb', 101 ); add_action( 'wp_head', 'wp_site_icon', 99 ); add_action( 'wp_head', 'wp_no_robots' );
很多回撥函式只與一個動作鉤子。設定priority
此處對於確保最重要的鉤子函式首先執行至關重要。
在上面的例子中,載入帶有wp_enqueue_scripts()
回撥函式的指令碼(priority = 1)比載入帶有wp_site_icon()
回撥函式的站點圖示元標記(priority = 99)更重要。
上面例子中使用的所有回撥函式都是WordPress函式。您也可以在任何程式碼中使用它們。有關更多資訊,請訪問我們工具頻道的開發寶典中的函式參考頁面。
其他動作函式
add_action()
是最常用的動作函式,而其實還有許多其他函式同樣有用。讓我們看看它們是如何工作的。
(1)has_action()
這個動作函式檢查一個動作是否已經被掛鉤。它接受兩個引數。第一個是動作的名稱。第二個引數是可選的,是回撥函式的名稱。
has_action( 'action_name', 'function_to_check' );
如果只指定第一個引數,則只要有任何函式連線到action_name
引數,都返回true
。
但是,如果您還指定了第二個引數,那麼如果指定的回撥函式未註冊到上述動作,那麼它將返回false
。如果它找到附加到動作動作的回撥函式,它將返回該動作鉤子上為該函式設定的priority
(整數)。
(2)do_action()
我們以前遇到過此動作函式。WordPress使用它來定義它的所有預設動作,使其他函式能夠鉤住它們。與WordPress一樣,您也可以使用do_action()
函式通過指定新動作名稱作為引數來建立新的自定義動作。
do_action( 'action_name', [argument1], [argument2] );
僅僅宣告這個函式本身不會做任何事情。但它將儲存在程式碼中,等待其他動作函式啟用它。傳遞任何額外的引數都是可選的,但如果希望回撥函式使用它們,這一點很重要。
此動作函式與do_action()
相同,只是有一個區別:通過它傳遞的任何引數都必須是陣列。當您有很多引數要傳遞,或者您的引數已經在陣列中時,此函式非常有用。
// here's an example array $arguments_array = array( 'arg_1', 'foo', true, 'arg_4' ); do_action_ref_array( 'example_action', $arguments_array );
由於PHP陣列是有序對映,因此請確保傳遞的引數順序正確。
此動作函式的使用示例是admin_bar_menu動作。它可以被掛鉤以新增、操作或刪除各種管理欄專案。所有管理欄專案都定義為陣列元素。
(4)did_action()
如果你想計算任何動作被觸發的次數,你可以呼叫這個動作函式。
did_action( 'action_name' );
此函式返回一個整數值。
當您只想在第一次執行動作時執行回撥函式時,did_action()
函式非常方便,參考示例程式碼判斷處理,以後不再執行。
function example_callback_function() { if( did_action( 'example_action' ) === 1 ) { // checks if the 'example_action' hook is fired once, and only runs then, and never again! } } add_action('example_action', 'example_callback_function');
這個動作函式移除一個與指定動作鉤子的回撥函式。例如,您可以使用此函式刪除連線到內建動作的預設WordPress函式,並將其替換為您自己的函式。
remove_action( 'action_name', 'function_to_be_removed', [priority] );
呼叫remove_action()
函式有幾個先決條件:
function_to_be_removed
和priority
引數必須與最初在add_action()
函式中使用的引數相同。- 不能直接呼叫該函式
remove_action()
,您需要從另一個函式內部呼叫它。 - 如果回撥函式是從類註冊的,那麼刪除它還有其他要求。您可以檢視WordPress Codex文件瞭解更多詳細資訊。
- 您不能在註冊回撥函式之前或執行回撥函式之後刪除它。
這是WooCommerce如何使用此動作函式刪除主商店頁面上的預設產品縮圖的示例。
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
這個動作函式刪除所有與動作鉤子的東西。優先順序引數是可選的。
remove_all_actions( 'action_name', [priority] );
請記住,不能從您要取消註冊回撥函式的動作中呼叫此函式。那會導致無限迴圈。您可以掛鉤之前觸發的動作以執行此函式而不會出現任何錯誤。
這個動作函式檢查指定的動作是否正在執行。它返回一個布林值(true
或false
)。
// check whether the 'action_name' action is being executed if ( doing_action( 'action_name' ) ) { // execute your code here }
您可以將action_name
引數留空以檢查是否正在執行任何動作。每次觸發任何動作時它都會返回true
。
// check if any action is running and do something if ( doing_action() ) { // the code here is run when any action is fired }
動作示例 1:向站點訪問者顯示維護訊息
有時,最好讓您的網站離線並設定維護中頁面。幸運的是,WordPress提供了一種簡單的方法來做到這一點。
// show a maintenance message for all your site visitors add_action( 'get_header', 'maintenance_message' ); function maintenance_message() { if (current_user_can( 'edit_posts' )) return; wp_die( '<h1>Stay Pawsitive!</h1><br>Sorry, we\'re temporarily down for maintenance right meow.' ); }
讓我們分解程式碼並完成每個步驟:
- get_header是在站點的頭模板檔案載入之前觸發的動作。如果您想中斷主站點的載入,這是一個完美的動作。
get_header
使用add_action()
帶有maintenance_message()
回撥函式的函式連線到動作中。- 定義
maintenance_message()
回撥函式。 current_user_can( 'edit_posts' )
是一個使用者能力測試函式,用於檢查當前使用者是否已登入並可以編輯文章。除了具有訂閱者角色的使用者之外,在WordPress站點上註冊的每個使用者都可以編輯文章。還有其他可靠的方法來執行此檢查,但我們將在這裡堅持使用這種簡單的方法。- 使用預設的wp_die()函式優雅地終止WordPress執行並顯示帶有錯誤訊息的HTML頁面。您可以在錯誤訊息引數中使用HTML語法對其進行格式化。
在我的自定義外掛中儲存程式碼後,我以隱私瀏覽模式載入了本地WordPress安裝。將在維護頁是成功的!
向站點訪問者顯示錯誤訊息
如果我在通過使用者能力測試時登入,該站點將成功載入。您現在可以繼續修復您的網站,同時它會向常客顯示此頁面。
如果您正在執行一個多作者部落格或為您的客戶管理一個站點,那麼您可能需要為非管理員使用者在WordPress儀表盤中隱藏某些管理選單。你可以通過掛鉤到admin_menu
動作來做到這一點。
// remove specific dashboard menus for non-admin users add_action( 'admin_menu', 'hide_admin_menus' ); function hide_admin_menus() { if (current_user_can( 'create_users' )) return; if (wp_get_current_user()->display_name == "Salman") return; remove_menu_page( 'plugins.php' ); remove_menu_page( 'themes.php' ); remove_menu_page( 'tools.php' ); remove_menu_page( 'users.php' ); remove_menu_page( 'edit.php?post_type=page' ); remove_menu_page( 'options-general.php' ); }
以下是上述程式碼片段的分步演練:
- admin_menu是在WordPress儀表盤區域中載入管理選單之前觸發的動作。
- 使用
add_action()
函式和hide_admin_menus()
回撥函式,以實現鉤住admin_menu
動作。 hide_admin_menus()
回撥函式定義的程式碼的邏輯。每次admin_menu
動作觸發時它都會執行。- 在回撥函式中,
current_user_can( 'create_users' )
函式檢查登入使用者是否為管理員。由於只有站點管理員具有create_user
功能,如果使用者是管理員,則該函式以return
宣告結束。 - WordPress的函式wp_get_current_user() 檢索當前使用者物件。通過這個函式,我們可以檢查登入使用者是否有設定特定的
display_name
。這是一個可選行,以防您想省略某些非管理員使用者由於此回撥函式而被鎖定。 - WordPress的函式remove_menu_page() 刪除頂級管理選單。在上面的程式碼示例中,我刪除了以下管理選單:外掛、主題、工具、使用者、頁面和選項。
儲存外掛檔案後,這是管理員登入的WordPress儀表盤的快照。
預設的WordPress管理儀表盤
這是非管理員使用者登入的WordPress儀表盤的螢幕截圖。
對非管理員使用者隱藏敏感的管理選單項
此解決方案僅隱藏指定的管理選單項,以免出現在WordPress儀表盤中。所有使用者仍然可以通過在瀏覽器中輸入選單URL來訪問它們。
要禁止某些使用者角色訪問特定選單,您需要編輯他們的能力。
掛鉤過濾器
過濾器為您的自定義程式碼提供了一種方法來修改其他WordPress功能使用的資料。與動作不同,掛鉤到過濾器的函式需要返回一個值。
add_filter() 過濾函式
您可以按照以下步驟將回撥函式掛接到過濾器:
- 定義一個回撥函式,它將在WordPress觸發過濾器時執行。過濾器的回撥函式需要至少指定一個引數,因為所有過濾器都至少將一個值傳遞給它們的回撥函式。
- 使用
add_filter()
函式將回撥函式註冊到過濾器。過濾器將負責呼叫回撥函式。根據WordPress Codex,add_filter()函式至少需要傳遞兩個引數:- 要掛鉤的過濾器的名稱。
- 過濾器觸發時將執行的回撥函式的名稱。
add_filter()
函式還接受兩個額外的可選引數來設定priority
和number of arguments
。這些引數的工作方式與add_action()
函式相同。
下面是一個示例,說明如何使用add_filter()
函式將回撥函式掛接到過濾器。
// define the filter callback function with at least one argument passed // the number of arguments that you can pass depends on how the filter is defined function filter_callback_function( $arg1, $arg2 ) { // make your code do something with the arguments and return something return $something; } // now hook the callback function to the 'example_filter' add_filter( 'example_filter', 'filter_callback_function', [priority], [no_of_args] ); // '10' is the default priority set for the callback function // and '1' is the default number of arguments passed
掛鉤過濾器的示例
WordPress提供了一個名為login_message的過濾器來過濾登入表單上方登入頁面上顯示的訊息。此過濾器返回的值可以帶有HTML標記。
讓我們掛入login_message
過濾器並修改登入螢幕上顯示的訊息。
// show a custom login message above the login form function custom_login_message( $message ) { if ( empty( $message ) ) { return "<h2>Welcome to Let's Develop by Salman Ravoof! Please log in to start learning.</h2>"; } else { return $message; } } add_filter( 'login_message', 'custom_login_message' );
if-else
回撥函式中的語句檢查登入訊息是否已經設定,主要是由另一個外掛或主題設定的。在這種情況下,回撥函式返回原始值,不做任何更改。這是避免與其他外掛或主題衝突的一種方法。
您可以在WordPress登入頁面的登入表單上方看到顯示的訊息。
在登入表單上方顯示自定義登入訊息
您可以通過將自定義樣式表排入佇列來設定登入頁面上所有元素的樣式。這樣做將允許您完全自定義預設的WordPress登入頁面。
您將在“使用鉤子自定義WordPress登入頁面”部分中瞭解如何使用動作鉤子載入自定義樣式表。
查詢WordPress支援的過濾器
在WordPress處理或修改資料的任何地方,您幾乎肯定可以找到一個過濾器來連線和更改它。將過濾器視為WordPress資料庫和瀏覽器之間的介面。
您可以在外掛API/過濾器參考頁面中找到WordPress支援的所有過濾器的詳盡列表。
WordPress提供了多種過濾器來掛鉤
那裡列出的所有過濾器都分為多個類別,並按照WordPress執行順序從上到下排列。
如果您想在WordPress原始碼中找到要掛鉤的過濾器,請搜尋術語“apply_filters”,您將獲得大量結果。在WordPress的程式碼參考也來搜尋隨機配備在WordPress,包括動作和過濾器一切的好地方。
WordPress核心如何使用過濾器
WordPress Core本身使用許多內建過濾器來修改其各種功能使用的資料。
例如考慮the_content過濾器。它在從資料庫中檢索到文章內容之後和在瀏覽器上顯示之前過濾文章內容。
就像動作一樣,您可以the_content
在wp-includes/default-filters.php
檔案中找到與鉤子相關的大多數WordPress Core過濾器函式。
add_filter()
是掛接到the_content
過濾器的所有核心函式的列表:
add_filter( 'the_content', 'do_blocks', 9 ); add_filter( 'the_content', 'wptexturize' ); add_filter( 'the_content', 'convert_smilies', 20 ); add_filter( 'the_content', 'wpautop' ); add_filter( 'the_content', 'shortcode_unautop' ); add_filter( 'the_content', 'prepend_attachment' ); add_filter( 'the_content', 'wp_make_content_images_responsive' ); add_filter( 'the_content', 'do_shortcode', 11 ); // AFTER wpautop().
請注意為某些回撥函式指定的優先順序。
例如,do_blocks()函式解析文章內容中的任何動態塊並重新渲染它們以與WordPress的新區塊編輯器相容。它指定了比預設值 (10) 更高的優先順序,以確保在執行其他功能之前內容已準備好塊。
convert_smilies()函式設定為較低的優先順序執行它的任務是將文字轉換表情影象精靈。在過濾所有文章內容後讓它在最後執行是有道理的。
有趣的事實:短程式碼是過濾器的一個子集。他們從短程式碼中獲取輸入,對其進行處理,然後將輸出返回給它。
其他過濾器函式
雖然add_filter()
是最常用的過濾函式,但還有許多其他有用的過濾函式。讓我們深入討論它們。
(1)has_filter()
此函式檢查指定的過濾器是否被任何函式掛鉤。它接受兩個引數。第一個引數用於輸入過濾器名稱。第二個引數是可選的,用於輸入回撥函式的名稱。
has_filter( 'filter_name', 'function_to_check' );
如果您僅指定第一個引數,則它會在任何函式filter_name
掛鉤時返回true
。
但是,如果您同時指定了這兩個引數,那麼如果提到的回撥函式未在給定的過濾器中註冊,它將返回false
。如果它找到了向過濾器註冊的回撥函式,那麼它會在此過濾器上返回該函式的priority
(整數)集。
has_filter()
函式的一種可能應用是檢查是否已經掛接了任何過濾器,並在此基礎上繼續執行程式碼。
// check to see if 'the_content' filter has been hooked if ( ! has_filter( 'the_content' ) { // hook the filter if and only if it hasn't been hooked before add_filter( 'the_content', 'modify_the_content' ); }
這個過濾器函式就像do_action()
動作函式。任何掛鉤到此過濾器的回撥函式都將在WordPress程式碼中此函式的任何位置執行。
您還可以使用此函式通過將過濾器名稱和過濾器值指定為引數來建立新的自定義過濾器。
apply_filters( 'filter_name', 'value_to_filter', [argument1], [argument2] );
如果要將它們傳遞給回撥函式,請不要忘記指定任何其他引數。大多數過濾器只使用一個引數,因此很容易錯過定義其他引數。
這個函式就像apply_filters()
函式一樣,除了它接受的所有引數都捆綁成一個陣列。
// an example array $arguments_array = array( 'some_value', 'foo', false, 'another_value' ); apply_filters_ref_array( 'example_filter', $arguments_array );
當您有許多引數要傳遞或所有引數都已在陣列中時,此過濾器函式會很方便。確保陣列內的引數順序正確。
此過濾器函式檢索當前正在執行的過濾器或動作的名稱。您不需要指定任何引數,因為它在回撥函式中執行。
下面是它的用法示例:
function example_callback() { echo current_filter(); // 'the_title' will be echoed return } add_filter( 'the_title', 'example_callback' );
儘管它的名字,這個函式可以檢索動作和過濾器的名稱。
此過濾器函式刪除附加到指定過濾器的回撥函式。它的工作原理與remove_action()
函式完全一樣。您可以使用它來刪除使用特定過濾器註冊的預設WordPress函式,並在必要時將其替換為您自己的函式。
remove_filter( 'filter_name', 'function_to_be_removed', [priority] );
要取消掛鉤到過濾器的回撥函式,function_to_be_removed
,並且priority
引數必須與掛鉤回撥函式時使用的引數相同。
如果過濾器是從類中新增的,通常是通過外掛新增的情況,那麼您需要訪問類變數以刪除過濾器。
// access the class variable first, and then remove the filter through it global $some_class; remove_filter( 'the_content', array($some_class, 'class_filter_callback') );
讓我們看看一個很好的例子remove_filter()
。
WooCommerce外掛使用wc_lostpassword_url()掛接到它的通話函式lostpassword_url過濾器重定向使用者的嘗試“忘記密碼?”。
它需要任何使用者單擊該連結到帶有URL的自定義前端頁面/my-account/lost-password
。如果沒有這個過濾器,它會將它們帶到標準的WordPress登入URL/wp-login.php
。
假設您要重置此函式並將您的使用者傳送到預設密碼檢索頁面 或完全單獨的頁面。您可以像這樣刪除此回撥函式:
remove_filter( 'lostpassword_url', 'wc_lostpassword_url', 10 );
此過濾器函式刪除註冊到過濾器的所有回撥函式。
remove_all_filters( 'filter_name', [priority] );
它的remove_all_actions()
函式類似。
流行的Advanced Excerpts外掛使用此函式刪除所有與the_excerpt
和get_the_excerpt
過濾器鉤子的預設函式。這樣做之後,它然後將自己的回撥函式掛接到過濾器。
// Ensure our filter is hooked, regardless of the page type if ( ! has_filter( 'get_the_excerpt', array( $advanced_excerpt, 'filter_excerpt' ) ) ) { remove_all_filters( 'get_the_excerpt' ); remove_all_filters( 'the_excerpt' ); add_filter( 'get_the_excerpt', array( $advanced_excerpt, 'filter_excerpt' ) ); }
此過濾器函式檢查指定的過濾器是否正在執行。
if ( doing_filter( 'save_post' ) ) { // run your code here }
它返回一個布林值(true
或false
)。
您應該注意此函式與current_filter()
返回正在執行的過濾器或動作的名稱(字串)的函式之間的區別。
過濾器示例 1:為評論新增敏感詞過濾器
管理WordPress網站上的所有評論可能是一個繁瑣的過程。 comment_text過濾器允許您設定規則,以便在將評論輸出到顯示器上之前對其進行修改。
帶有敏感詞標記的未經過濾的評論
您可以指示WordPress在任何敏感詞顯示給您的網站訪問者之前自動刪除它們。
// hook into the 'comment_text' filter with the callback function add_filter( 'comment_text', 'the_profanity_filter' ); // define a callback function to filter profanities in comments function the_profanity_filter( $comment_text ) { // define an array of profane words and count how many are there $profaneWords = array('fudge', 'darn', 'pickles', 'blows', 'dangit'); $profaneWordsCount = sizeof($profaneWords); // loop through the profanities in $comment_text and replace them with '*' for($i=0; $i < $profaneWordsCount; $i++) { $comment_text = str_ireplace( $profaneWords[$i], str_repeat('*', strlen( $profaneWords[$i]) ), $comment_text ); } return $comment_text; }
這是程式碼的逐行細分:
- comment_text是一個過濾器鉤子,允許您在瀏覽器顯示之前修改評論的文字。您可以向它註冊回撥函式以過濾其輸出。
- 通過
add_filter()
函式,您可以連線到comment_text
過濾器併為其附加回撥函式。 the_profanity_filter()
是回撥函式的名稱。它只接受一個引數,即一個包含評論文字的字串。使用適當的程式碼邏輯定義此自定義函式。- 將所有敏感詞儲存在名為
profaneWords
的PHP陣列中。您可以向該陣列新增任意數量的單詞。在PHP函式sizeof()的幫助下,我將這個陣列的大小儲存在profaneWordsCount
變數中。 - 迴圈遍歷所有敏感詞,並使用PHP的預設str_ireplace() 函式將任何匹配的敏感詞替換為
*
符號。由於這是一個不區分大小寫的字串替換函式,因此您不必擔心大小寫。檢視執行搜尋和替換的不同方法。 - 使用
return
輸出過濾後的評論文字。
將更改儲存到您的自定義外掛檔案並重新載入任何帶有評論的文章。您包含在profaneWords
陣列中的所有單詞現在都應替換為“ *”符號。
審查帶有“*”符號的評論中的敏感詞
原始評論仍將在資料庫中保持原樣。此過濾器僅在將評論文字輸出到前端之前對其進行修改。
網站後臺原評論
一旦你使用了正確的過濾器,你就可以用它做很多很酷的事情。
例如,您還可以使用comment_text
過濾器從所有評論中刪除任何 URL(請務必閱讀有關如何阻止WordPress中的垃圾評論的深入指南)。
或者,您可以連線到pre_comment_approved過濾器,並根據預定義的標準將評論標記為已批准、垃圾郵件或駁回。
過濾器示例 2:在文章後插入內容
您已經看到WordPress如何使用the_content
過濾器來修改文章或頁面內容。讓我們使用相同的過濾器在每篇文章的末尾新增一些內容。
// hook into 'the_content' filter with a callback function add_filter( 'the_content', 'insert_content_below' ); // define the callback function to insert something below the post function insert_content_below( $content ) { // check to see if we're inside the main loop in a single post if ( is_single() && in_the_loop() && is_main_query() ) { return $content . "<h3 style=\"text-align: center;\">Let me insert myself here</h3><p style=\"text-align: center;border: 3px solid #5333ed;\">I'll appear after the post. You can insert anything here. Even HTML. Headers, links, images, scripts, I'll take them all and append it to the end of the post content. You can also give me a class, so you can style me easily with CSS style sheets.</p>" ; } return $content; }
理解上面例子中的程式碼邏輯:
the_content
過濾器鉤子可幫助您獲取當前文章的內容並對其進行自定義。- 使用
add_filter()
函式通過insert_content_below()
回撥函式鉤住the_content
過濾器。 - 通過將當前文章的內容作為引數 (
$content
)傳遞來定義回撥函式。 - 在回撥函式中,檢查您是否只過濾了主查詢中的內容,在本例中是文章內容。如果您不驗證這一點,有時程式碼會無意中過濾來自其他地方的內容,例如側邊欄和頁尾。
- is_main_query()和in_the_loop()條件確定查詢是否為主查詢以及是否發生在主WordPress迴圈中。
- is_single()條件檢查查詢是否針對單個文章。
- 使用PHP的字串連線運算子(
$content . "your additions"
) 向頁面內容新增額外內容。 - 如果上述所有條件都檢查出來,則
return
過濾後的評論。如果沒有,則只返回內容而不做任何更改。
儲存您的外掛檔案,載入您網站上的任何文章,然後滾動到最後。
在文章內容的末尾插入一些東西
通過反轉字串連線引數 ( "your additions" . $content
)的位置,您可以使用相同的邏輯在所有文章的開頭新增任何內容。
使用鉤子自定義WordPress登入頁面
讓我們同時使用動作和過濾器鉤子來自定義預設的WordPress登入頁面。我將建立一個名為Sal Custom Login Page的新外掛來執行此動作。您可以在本節末尾找到此外掛的完整原始碼。
最終定製的WordPress登入頁面
讓我們開始新增標準外掛標題欄位並將其註冊到WordPress。
<?php /* Plugin Name: Sal Custom Login Page Version: 1.0 Description: Demonstrating WordPress Hooks (Actions and Filters) by customizing the WordPress login page. Author: Salman Ravoof Author URI: https://www.salmanravoof.com/License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Text Domain: sal-custom-login-page */ // enqueueing the custom style sheet on WordPress login page add_action( 'login_enqueue_scripts', 'salhooks_login_stylesheet'); function salhooks_login_stylesheet() { // Load the style sheet from the plugin folder wp_enqueue_style( 'sal-custom-login-page', plugin_dir_url( __FILE__ ).'sal-custom-login-page-styles.css' ); }
首先,login_enque_scripts動作鉤子將您的自定義樣式表排入佇列。您在此處排隊的任何指令碼或樣式都包含在登入頁面的標題部分中。
如果您想在站點的前端(而不是在管理後端或登入區域)載入自定義指令碼和樣式表,那麼您需要掛接到wp_enqueue_scripts
動作。您可以在WordPress Codex和關於如何使用wp_enqueue_scripts的文章中閱讀更多相關資訊。
在salhooks_login_stylesheet()
回撥函式中,使用wp_enqueue_style()函式載入放置在同一外掛目錄中的自定義樣式表 (sal-custom-login-page-styles.css
)。WordPress的內建plugin_dir_url( __FILE__ )函式可以輕鬆獲取當前外掛目錄的URL路徑(帶有斜槓)。
我不會解釋這裡應用的CSS樣式,但您可以在本節末尾連結的原始碼中找到它們。
// Custom login ERROR message to keep the site more secure add_filter( 'login_errors', 'salhooks_remove_login_errors', 10 ); function salhooks_remove_login_errors() { return 'Incorrect credentials. Please try again!'; }
接下來,login_errors過濾器鉤子更改當有人輸入錯誤憑據時顯示的錯誤訊息。過濾錯誤訊息將阻止攻擊者輕鬆猜測您的使用者名稱。
// Remove the login form box shake animation for incorrect credentials add_action( 'login_head', 'remove_login_error_shake' ); function remove_login_error_shake() { remove_action( 'login_head', 'wp_shake_js', 12 ); }
每次有人輸入錯誤的登入憑據時,登入表單框都會劇烈晃動。這是一個可選步驟,但我將其包含在內是為了表明您還可以從登入頁面中刪除某些功能。
您將在本文的最後一節中瞭解有關remove_action()
和remove_filter()
函式的更多資訊。
// Change the logo and header link above the login form add_filter( 'login_headerurl', 'salhooks_login_headerurl'); function salhooks_login_headerurl( $url ) { $url = 'https://salmanravoof.com'; return $url; } add_filter( 'login_headertext', 'salhooks_login_headertext'); function salhooks_login_headertext( $text ) { $text = 'Salman Ravoof'; return $text; }
最後一步是更改登入標題的URL和文字。您可以連線到login_headerurl和login_headertext過濾器來修改它們。
如果您想在此外掛的基礎上構建並進一步試驗,您可以下載該外掛的原始碼並開始使用。
WordPress鉤子列表和資源
很難記住WordPress的所有各種鉤子。有數以千計的內建動作和過濾器可供使用。因此,找到一個合適的鉤子有時感覺就像是在尋寶。
值得慶幸的是,您可以使用各種資源來確定滿足您需求的完美鉤子。
第一個熟悉鉤子的地方是WordPress Codex,尤其是外掛手冊中的鉤子部分。在這裡您可以找到有關鉤子和連結的基本資訊,以完成有關所有動作和過濾器鉤子的文件。
使用WordPress外掛手冊開始學習鉤子
為外掛手冊中的這些有用連結新增書籤以加快搜尋速度:
動作參考和過濾器參考頁面都會為您提供通常在特定WordPress請求期間執行的所有鉤子的列表。
例如,您可以找到訪問管理頁面、處理文章頁面附件或類別時觸發的所有鉤子。
WordPress Codex還包括一個方便的搜尋工具,用於查詢其所有函式、鉤子、方法和類。此頁面還列出了最新版本的WordPress中的新元件和更新元件。如果您想了解WordPress內部發生的事情,請先前往這裡。
在此處搜尋WordPress內的任何內容
這個WordPress鉤子索引按型別、它們首次亮相的WordPress版本以及它們是否被棄用對所有鉤子進行排序。
Adam R Brown的WordPress鉤子索引
按照它們的出現順序對鉤子進行排序會告訴你,最古老的WordPress鉤子仍然是最常用的。如果您不熟悉WordPress開發,熟悉這些流行的動作和過濾器是最快的方法。
雖然此索引自WordPress 5.1以來尚未更新,但瀏覽所有主要鉤子仍然很有幫助。
仍然很難找到你想要的鉤子嗎?使用正確的關鍵字進行線上搜尋始終是一個很好的開始方式。如果其他一切都失敗了,您可以隨時深入研究WordPress程式碼。
查詢在WordPress頁面上註冊的鉤子
正如我們所見,WordPress有大量可用的鉤子,但並非每個鉤子都會在每個頁面上觸發。如果您能找到可以在特定頁面上掛鉤的動作和過濾器,那麼您就贏了一半。
雖然您可以使用xdebug和PHPCS等高階PHP除錯工具來幫助解決此問題,但您可以在WordPress中執行更簡單的開發工具,例如除錯欄和查詢監視器。
帶有動作和過濾器外掛的除錯欄
Debug Bar是一個官方的WordPress外掛,它為您的管理欄新增了一個Debug選單。它顯示PHP警告和通知、快取請求、MySQL查詢和其他有用的除錯資訊。
注:此外掛最近未更新,也未使用WordPress的最新主要版本進行測試。我們提到它是一個方便的外掛,用於瞭解有關WordPress鉤子的更多資訊。
WordPress外掛-Debug Bar
安裝外掛後,您需要將下面的程式碼片段新增到您網站的wp-config.php
檔案中以啟用其除錯功能。
define( 'WP_DEBUG', true ); // tracks PHP Warnings and Notices define( 'SAVEQUERIES', true ); // tracks and displays MySQL queries
您現在應該會在管理欄中看到Debug選單選項。單擊它會將您帶到其儀表板,在那裡您可以看到附加到您訪問它的頁面的各種查詢和快取。
WordPress管理欄中的“Debug”選單
接下來,您需要安裝Debug Bar Actions and Filters Addon外掛。這是一個方便的擴充套件程式,它將向您的除錯欄儀表板新增另外兩個選項卡,以顯示在當前請求上觸發的動作和過濾器鉤子。
按當前頁面載入順序列出的動作鉤子
它還將列出所有與其優先順序鉤子的函式。
列出的過濾器及其優先順序和註冊的回撥函式
您可以從站點上的任何頁面單擊Debug選單,以瞭解可以在該頁面上掛鉤的所有動作和過濾器。
Query Monitor
Query Monitor是一個強大的WordPress開發者工具面板。您可以使用它來深入瞭解頁面上可用的鉤子及其載入順序。
WordPress外掛-Query Monitor
與除錯欄不同,您無需安裝任何外掛即可檢視在特定頁面上觸發的動作和過濾器。
您可以從管理欄訪問Query Monitor
Query Monitor還為您提供了有關從哪裡觸發鉤子的更多資訊。
Query Monitor中的Hooks & Actions面板
在元件列中,您可以看到大部分鉤子都是從Core註冊的。但是有些鉤子是從主題或外掛註冊的。可以從多個元件註冊一些鉤子。
您可以使用鉤子和元件下拉選單僅檢視您需要的鉤子。
注意: Query Monitor使用“Hooks”作為動作和過濾器的統稱,但它將註冊的回撥函式稱為“動作”。從技術上講,這是一個錯誤的定義,可能會使您感到困惑,因此請記住這一點。
您可以做的不僅僅是使用Query Monitor檢查所有查詢和請求。它還包括高階功能,例如列表樣式、指令碼、語言、Ajax呼叫、使用者能力檢查和REST API呼叫。
“所有”鉤子
WordPress有一個名為“all”的特殊鉤子,您可以鉤住它來為每個鉤子執行回撥函式,無論它是否已全部註冊。這對於除錯頁面崩潰或您想知道特定事件何時發生非常有用。
例如,您可以使用all
下面示例中的鉤子來echo
執行所有正在執行的動作。
// echo all the actions being run function debug_helper_function(){ echo '<p>' . current_action() . '</p>'; } add_action( 'all', 'debug_helper_function' );
上面定義的debug_helper_function()
將在觸發任何動作時執行。瞭解上次執行動作是什麼將使您更好地瞭解需要檢視的位置。
WordPress鉤子儲存在哪裡?
WordPress使用WP_Hook類來實現鉤子的工作方式。這個核心類用於處理所有內建的WordPress動作和過濾器。您可以在wp-includes/class-wp-hook.php檔案中找到幾乎所有與此類相關的程式碼。
從技術上講,WP_Hook
該類是一個物件陣列,包括回撥、迭代、current_priority、nesting_level和doing_action等屬性。它還定義了許多有用的鉤子函式,可以使用WP_Hook方法呼叫這些函式。
大多數WordPress開發人員不必太擔心WordPress儲存鉤子的位置,只要他們遵守外掛API指南即可。
如何建立自定義WordPress鉤子
您已經看到WordPress通過其外掛API提供的各種鉤子。您還了解了如何使用預設鉤子將您自己的程式碼注入WordPress runtime。
如果您是外掛或主題開發人員,最好為其他開發人員提供一種以相同方式與您的程式碼進行互動的方式。自定義鉤子可讓您做到這一點。它們允許其他開發人員擴充套件和修改您的外掛和主題的功能。
建立您自己的動作和過濾器相當簡單。您可以使用與WordPress Core相同的函式來建立鉤子。讓我們看幾個例子。
如何在WordPress中建立自定義動作
使用do_action()
函式建立自定義動作鉤子。這是你如何做到的:
// the position where you insert your action is where it'll run when called do_action( ' my_unique_custom_action' ); // continue with the rest of your code
現在,其他開發人員無需修改原始碼即可連線到您的外掛或主題。他們所要做的就是使用該add_action()函式將他們的回撥函式註冊到您外掛的自定義動作中。
add_action( 'my_unique_custom_action', 'some_callback_function' ); // define the callback function you mentioned in the above action function some_callback_function() { // this code will run wherever your custom action hook is }
確保徹底記錄(document)您的自定義鉤子,詳細解釋它們的作用。畢竟,建立自定義鉤子的主要用途是幫助其他開發人員與您的程式碼進行互動。
如何在WordPress中建立自定義過濾器
使用apply_filters()
函式建立自定義過濾器鉤子。您可以這樣做:
$value_to_filter = "I'm a string, but this can be any PHP data type"; // filters modify a value and are typically tied to a predefined variable apply_filters( 'my_custom_filter', $value_to_filter );
您的自定義過濾器的引數應包括唯一識別符號和要過濾的值。其他開發人員可以使用add_filter()
函式連線到您的自定義過濾器並修改傳遞的值。
add_filter( 'my_custom_filter', 'some_callback_function' ); // define the callback function you mentioned in the above filter function function some_callback_function( $value_to_filter ) { // modify the passed value (or not) return $value_to_filter; // returning a value is a must for filters }
當您定義自定義過濾器時,請確保它沒有定位在它應該過濾的值被定義之前。如果您沒有正確放置過濾器,過濾後的值將被預設值覆蓋。
自定義鉤子命名約定
為所有自定義鉤子選擇唯一名稱非常重要。由於任何外掛或主題都可以有自己的自定義鉤子,因此具有相同的鉤子名稱可能會導致程式碼衝突和意外結果。
例如,如果您將動作命名為send_email
,其他外掛開發人員很可能也會選擇相同的術語,因為它不夠獨特。如果任何網站同時安裝了您和其他開發人員的外掛,則可能會導致難以追蹤的錯誤。
您可以為所有自定義鉤子新增一個通用識別符號作為字首,以使它們既簡單又獨特。因此,您可以為其命名plugin_name_send_email
(plugin_name_
是此處的唯一字首),而不是send_email
。
帶有可擴充套件外掛的自定義鉤子演示
讓我們建立一個可擴充套件外掛(或可插拔外掛),允許其他開發人員使用其自定義鉤子與其互動。
我將這個外掛命名為Custom Hooks Demo 。它的主要功能是在您插入短程式碼的任何地方輸出一個引用框。它將在正確的位置包含自定義動作和過濾器,以便其他開發人員可以修改或擴充套件其功能。
您可以參考我的WordPress簡碼指南以瞭解有關簡碼如何工作的更多資訊。
讓我們開始使用可擴充套件外掛。
<?php /* Plugin Name : Custom Hooks Demo Description : Demonstrating how to create an extensible WordPress plugin using custom hooks. Author : Salman Ravoof Author URI : https://salmanravoof.com/ License : GPLv2 or later License URI : https://www.gnu.org/licenses/gpl-2.0.html Text Domain : custom-hooks-demo */ /** * the [custom_hooks_demo] shortcode returns the HTML code for a quote box. * @return string HTML code for a quote box */ add_shortcode( 'custom_hooks_demo', 'my_shortcode_callback' ); function my_shortcode_callback ( $arguments ) { ob_start(); // start object buffering to collect all output before sending it to the browser // set an action hook to run before you output anything do_action( 'the_topmost_custom_action' ); // define your variables which you want to allow to be filtered $quote_content = "Z.E.R.O. That's the number of people who'd like to have any website autoplay music on their browsers."; $quote_author = "John Doenuts"; // create your custom filters after you've set the variables $quote_content = apply_filters( 'custom_quote_content', $quote_content ); $quote_author = apply_filters( 'custom_quote_author', $quote_author ); // build the shortcode output template echo "<div style=\"border:3px solid #5333ed;\"><blockquote style=\"margin:20px;border-color:#5333ed;\">"; echo $quote_content; echo "<br><br>"; echo "― <strong>" . $quote_author . "</strong>"; echo "</blockquote></div>"; // set an action hook to run after you output everything do_action( 'the_ending_custom_action' ); return ob_get_clean(); // get buffer contents, delete the buffer, and then stop buffering }
add_shortcode()
函式用於建立自定義短程式碼。然後您使用該外掛的所有函式定義短程式碼的回撥函式。- ob_start()是一個啟用輸出緩衝的PHP函式。這是一個超級方便的函式,它指示PHP保留伺服器緩衝儲存器中的任何輸出,而不是立即輸出。您可以使用它在PHP中構建複雜的、可讀的HTML程式碼。
do_action( 'the_topmost_custom_action' )
定義您的第一個自定義動作。為了使它有用,您需要在外掛輸出任何內容之前定義它。其他開發人員可以連線到這個自定義動作來執行他們的程式碼,然後這個自定義短程式碼列印出任何東西。- 建立要過濾的變數。在這個外掛中,這些變數是
$quote_content
和$quote_author
。在本例中它們都是字串,但您可以將它們設定為任何PHP資料型別(例如整數、布林值、陣列)。 - 使用該
apply_filters()
函式建立您的自定義過濾器。由於所有過濾器都返回一個值,因此您可以將先前定義的變數分配給此過濾器的返回值。其他開發人員現在可以連線到這個過濾器來修改預定義變數的預設值。 - 使用
echo
語句逐行構建短程式碼的輸出。由於我們啟用了輸出緩衝,因此沒有任何輸出會立即到達瀏覽器。 do_action( 'the_ending_custom_action' )
定義您的最後一個自定義動作。您需要在最後定義它,但在返回所有緩衝區內容之前。- ob_get_clean()是預設的三合一PHP函式。它將檢索緩衝區內容,消除所有緩衝區資料,然後停止輸出緩衝。它將以單個串聯字串的形式
return
收集的緩衝區內容。
儲存並啟用後,將[custom_hooks_demo]
短程式碼新增到您的文章內容將輸出一個帶有預設值的引用框。
使用Custom Hooks Demo外掛的原始引用框
現在,讓我們建立另一個名為Custom Hooks Demo Extension的外掛。它將掛鉤到由前一個外掛建立的所有自定義鉤子並執行或修改某些內容。
<?php /* Plugin Name : Custom Hooks Demo Extension Description : Demonstrating how you can extend WordPress plugin functionality with its custom hooks. Author : Salman Ravoof Author URI : https://salmanravoof.com/ License : GPLv2 or later License URI : https://www.gnu.org/licenses/gpl-2.0.html Text Domain : custom-hooks-demo-extension */ /** * replace the quote content by hooking into the 'custom_quote_content' filter */ add_filter( 'custom_quote_content', 'new_quote_content_callback' ); function new_quote_content_callback( $content ) { $content = "There are no bugs in programming. Only unexpected features."; return $content; } /** * replace the quote author by hooking into the 'custom_quote_author' */ add_filter( 'custom_quote_author', 'new_quote_author_callback' ); function new_quote_author_callback( $author ) { $author = "Jane Doodle"; return $author; } /** * add an image to the top of the shortcode output by hooking into the 'the_topmost_custom_action' */ add_action( 'the_topmost_custom_action', 'quote_image_callback' ); function quote_image_callback() { $url = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Quote-right-cs.svg/75px-Quote-right-cs.svg.png"; echo '<div><img class="aligncenter" src="'.$url.'"></div>'; } /** * add a button below the shortcut output by hooking into the 'the_ending_custom_action' */ add_action( 'the_ending_custom_action', 'add_button_callback' ); function add_button_callback() { echo '<div style="text-align:center;"><button name="nice">Nice Quote!</button></div>'; }
如您所見,此擴充套件外掛僅包含在正確位置掛鉤到原始外掛以進行修改的動作和過濾器函式。
它使用add_action()
和add_filter()
函式將其回撥函式註冊到由原始外掛(例如the_topmost_custom_action
,custom_quote_author
)建立的自定義動作和過濾器。
擴充套件外掛修改原引用框
自定義動作鉤子允許您在原始外掛中以正確的時間間隔插入您的程式碼並執行您自己的指令碼。在這裡,我們在頂部新增一個影象,在底部新增一個按鈕。
同樣,自定義過濾器鉤子可讓您修改引用內容的值及其作者姓名。最終的結果是一個任何人都可以完全擴充套件而無需修改其原始碼的外掛。
使用來自第三方開發者的自定義鉤子
自定義鉤子使單個WordPress外掛和主題能夠擁有豐富的可擴充套件外掛生態系統。參考WooCommerce外掛。它為WordPress新增了電子商務功能,但它還在其程式碼中包含了大量鉤子。
WooCommerce動作和過濾器鉤子參考
WooCommerce有數百個擴充套件和外掛,它們使用其鉤子來構建其核心功能並使其變得更好。
您可以使用這些擴充套件將WooCommerce與Stripe、MailChimp、Salesforce、Zapier等整合。
擴充套件擴充套件了WooCommerce的功能
一個好的做法是檢視流行的WordPress外掛的文件部分,看看它們是如何實現自定義鉤子的。我的一些主要建議是Easy Digital Downloads、BuddyPress、Quiz and Survey Master以及Gravity Forms。
何時使用自定義鉤子?
根據您正在建立的主題或外掛,以及它的目標使用者,您可能想知道是否需要新增任何自定義鉤子。
在決定是否新增自定義鉤子時,一個好的經驗法則是檢查它們是否為其他開發人員提供了任何可擴充套件性好處。如果沒有,那麼最好推遲到其他開發人員要求您新增它們。
您需要非常確定將自定義鉤子新增到您的外掛或主題。一旦釋出,並且如果其他開發人員已經使用過它,那麼在不破壞向後相容性的情況下您永遠無法更改它。
從WordPress鉤子中刪除回撥函式
您已經看到了如何刪除註冊到某些鉤子的回撥函式的示例。這些回撥可以由外掛、主題甚至WordPress核心本身註冊。讓我們用更多的例子來看看移除鉤子的回撥函式。
要從鉤子中刪除回撥函式,取決於它是註冊到動作還是過濾器,您需要使用remove_action()
或remove_filter()
函式。
一個警告是,您需要使用用於註冊回撥函式的相同引數來呼叫這些函式。基本上,從它們add_action()
或add_filter()
函式中複製貼上引數。
此外,您只能在註冊後刪除回撥函式。如果您在註冊之前嘗試刪除它們,則刪除過程將失敗。您需要正確獲取鉤子的執行順序。
假設您想刪除一個主題註冊的回撥函式,該函式會給您的網站增加膨脹(您想要一個速度更快的網站,不是嗎?)。
function wp_bloated_callback_function() { // some code that adds a lot of bloat to the site } add_action( 'template_redirect', 'wp_bloated_callback_function', 5 );
例如,上面的回撥函式可能會載入許多不必要的指令碼和樣式表。刪除它會給您的網站帶來巨大的效能提升。
但是,您需要確保remove_action()
函式僅在template_redirect動作之後執行。一種方法是after_setup_theme動作鉤子,因為它是在template_redirect
動作之後觸發的。
function wp_remove_bloat() { // ensure all parameters are identical to the original add_action() function remove_action( 'template_redirect', 'wp_bloated_callback_function', 5 ); } // ensure that remove_action() is called only after add_action() add_action( 'after_setup_theme', 'wp_remove_bloat' );
在wp_bloated_callback_function()
現在將從放掉自身template_redirect
的行動。
刪除回撥函式的特殊情況
刪除回撥函式不僅僅是完全禁用它們。有時您可能需要暫時刪除它們,執行您的程式碼,然後再次新增它們。
例如,每次呼叫wp_insert_post()
和wp_publish_post()
函式時,都會觸發save_post動作。您可以在wp-includes/post.php
找到它們。
因此,如果您有一個回撥函式掛接到save_post
動作,並且如果您在回撥函式中呼叫wp_insert_post()
或wp_publish_post()
函式,save_post
動作將多次觸發。
function some_callback_function( $post_id, $post ) { // do something here wp_insert_post( [some_array] ); // this function also calls the 'save_post' action // maybe do something more } add_action( 'save_post', 'some_callback_function', 10, 2 );
呼叫動作的函式也呼叫它可能會產生意想不到的結果。解決此問題的一種方法是remove_action()
在呼叫wp_insert_post()
.
function some_callback_function( $post_id, $post ) { // do something here // remove the callback function from the ‘save_post’ action remove_action( 'save_post', 'some_callback_function', 10, 2 ); // now run the wp_insert_post() function wp_insert_post( [some_array] ); // add the callback function back to the ‘save_post’ action add_action( 'save_post', 'some_callback_function', 10, 2 ); // maybe do something more } add_action( 'save_post', 'some_callback_function', 10, 2 );
這是remove_action()
或remove_filter()
函式的另一個實際用途。深入挖掘WordPress的核心將幫助您瞭解如何更好地避免這些情況。
其他WordPress鉤子教程
- 手動將程式碼新增到WordPress頁首和頁尾
- 您的WordPress媒體庫完整指南
- 如何建立和修改WordPress Cron作業
- 如何建立WordPress子主題
- 禁用WordPress外掛載入特定頁面和文章
- 使用程式碼禁用WordPress中的表情符號
小結
如果您是WordPress開發人員,則使用WordPress鉤子有多種優勢。
鉤子不僅可以讓您修改或擴充套件WordPress的核心功能,還可以使用它們來修改外掛、主題,並讓其他開發人員與您的外掛或主題進行互動。
評論留言
脣槍舌劍 (2)
xu
2022.8.28 13:08
文章都是自己码的吗? 乍一看还以为是爬的外文再翻译
WBOLT_COM
2022.8.28 21:08
机翻加人工翻,不是采集,手动搬运。有启发?