我們在 WordPress 發表文章的時候,有時會遇到一些特殊的需求,比如把文章中的連結變成可點選,或者過濾掉文章內容 HTML 標籤中的某種屬性等。

我近期的專案中就遇到了後面的這個需求,因為直接貼上複製網路上的文章,往往會夾帶著 HTML 的 class 、 id 和 style 屬性值,這些無用的內容會潛在的影響正文的排版佈局和樣式,所以要過濾掉。

解決思路

如果想要過濾掉髮布文章時,文章內容中 HTML 標籤中的 class 、 id 和 style 等屬性,首先需要在摁下 「發表」 按鈕的時候,使用 PHP 正則匹配對要發表的文章內容進行正則匹配處理,替換掉無用的內容,最後繼續執行插入資料庫的操作。所以這個問題就分成了幾個小步驟:

  1. 「獲取」 文章內容,傳遞給處理函式
  2. 處理函式使用正則匹配對文章內容進行處理
  3. 將處理好的內容返回,讓 WordPress 把內容插入資料庫

解決方案

面對第一個步驟,WordPress 有一個很強大的 「鉤子」(hook) 開發機制,實現各種功能和開發外掛必不可少的功能。簡單的說,就是 WordPress 在執行某些關鍵性的操作時 (例如發表文章、發表評論、修改文章、刪除文章、新增使用者等等),會插入一個 「鉤子」,這樣你就可以在 functions.php 中或者外掛中,使用 add_action 或者 add_filter 函式掛上這個 「鉤子」,並增加自定義的函式對資料進行一個動作或者進行過濾。

例如在發表文章的時候,在提交到插入資料庫之前,會有一個叫做 wp_insert_post_data 「鉤子」,如果你想對文章進行過濾處理,你就需要在 functions.php 檔案中,新建一個處理函式,然後將對應處理函式繫結到這個鉤子上面。

首先,你需要找到你要用的 「鉤子」,你需要瀏覽 WordPress 官方的 Filter Reference 和 Action Reference 檔案,裡面是長長的 「鉤子」 列表,看一下下面的說明,然後找到對應的 「鉤子」 就可以開始使用了。比較常用的 「鉤子」 已經給出官方檔案和使用說明瞭,例如:wp_insert_post_data,不過由於列表太長了,大部分的沒有給出很詳細的使用說明,就需要你按照經驗來使用。

找到需要的 「鉤子」 之後,使用 add_filter 函式 (具體用法可以看一下官方檔案:add filter) 將鉤子和處理函式進行掛鉤函式用法如下:

add_filter($tag,  $function_to_add,  $priority = 10,  $accepted_args = 1);

就本例而言,基本結構如下:

<?php
function wpjam_insert_post_data( $data , $postarr ) {
  // 處理函式的邏輯部分和功能程式碼
  return $data;
}

add_filter( 'wp_insert_post_data', 'wpjam_insert_post_data', '99', 2 );
?>

這樣,我們的第一個步驟就完成了。下面來編寫函式的處理程式碼。既然要過濾文章中的具有某些特徵的程式碼,所以需要使用 PHP 的正則匹配替換掉。可以使用如下的 PHP 程式碼:

$date = preg_replace('/<([a-z]+?)s+?.*?>/i', '<$1>', $date);

根據 wp_insert_post_data 檔案可以看出,傳遞進去的 $data 陣列裡面是文章的相關資訊,我們需要處理的是正文內容,所以使用 $date[『post_content』] 和 $date[『post_content_filtered』] 這兩個變數,那麼就可以寫出下面這段程式碼:

function wpjam_insert_post_data( $data , $postarr ) {

    $date['post_content_filtered'] = preg_replace('/<([a-z]+?)s+?.*?>/i', '<$1>', $date['post_content_filtered']);
    $date['post_content'] = preg_replace('/<([a-z]+?)s+?.*?>/i', '<$1>', $date['post_content']);

  return $data;
}

add_filter( 'wp_insert_post_data', 'wpjam_insert_post_data', '99', 2 );

因為函式裡面已經將處理後的資料 return 了,這樣第二步和第三步就完成了,我們的這個需求也就實現了。

總結

正是因為有了這種開發機制,WordPress 的靈活性和擴充套件性大大增強。如果你還想對文章進行其他處理 (例如文章末尾加版權資訊等),都可以繼續編寫函式,掛鉤在對應的鉤子即可。