我們?cè)?WordPress 發(fā)表文章的時(shí)候,,有時(shí)會(huì)遇到一些特殊的需求,,比如把文章中的鏈接變成可點(diǎn)擊,,或者過(guò)濾掉文章內(nèi)容 HTML 標(biāo)簽中的某種屬性等,。
我近期的項(xiàng)目中就遇到了后面的這個(gè)需求,,因?yàn)橹苯诱迟N復(fù)制網(wǎng)絡(luò)上的文章,,往往會(huì)夾帶著 HTML 的 class,、id 和 style 屬性值,,這些無(wú)用的內(nèi)容會(huì)潛在的影響正文的排版布局和樣式,所以要過(guò)濾掉,。
解決思路
如果想要過(guò)濾掉發(fā)布文章時(shí),,文章內(nèi)容中 HTML 標(biāo)簽中的 class、id 和 style 等屬性,,首先需要在摁下“發(fā)表”按鈕的時(shí)候,,使用 PHP 正則匹配對(duì)要發(fā)表的文章內(nèi)容進(jìn)行正則匹配處理,替換掉無(wú)用的內(nèi)容,,最后繼續(xù)執(zhí)行插入數(shù)據(jù)庫(kù)的操作,。所以這個(gè)問(wèn)題就分成了幾個(gè)小步驟:
- “獲取”文章內(nèi)容,傳遞給處理函數(shù)
- 處理函數(shù)使用正則匹配對(duì)文章內(nèi)容進(jìn)行處理
- 將處理好的內(nèi)容返回,,讓 WordPress 把內(nèi)容插入數(shù)據(jù)庫(kù)
解決方案
面對(duì)第一個(gè)步驟,,WordPress 有一個(gè)很強(qiáng)大的“鉤子”(hook)開(kāi)發(fā)機(jī)制,實(shí)現(xiàn)各種功能和開(kāi)發(fā)插件必不可少的功能,。簡(jiǎn)單的說(shuō),,就是 WordPress 在執(zhí)行某些關(guān)鍵性的操作時(shí)(例如發(fā)表文章、發(fā)表評(píng)論,、修改文章,、刪除文章、新增用戶等等),會(huì)插入一個(gè)“鉤子”,,這樣你就可以在functions.php中或者插件中,,使用add_action或者add_filter函數(shù)掛上這個(gè)“鉤子”,并增加自定義的函數(shù)對(duì)數(shù)據(jù)進(jìn)行一個(gè)動(dòng)作或者進(jìn)行過(guò)濾,。
例如在發(fā)表文章的時(shí)候,,在提交到插入數(shù)據(jù)庫(kù)之前,會(huì)有一個(gè)叫做wp_insert_post_data“鉤子”,,如果你想對(duì)文章進(jìn)行過(guò)濾處理,,你就需要在functions.php文件中,新建一個(gè)處理函數(shù),,然后將對(duì)應(yīng)處理函數(shù)綁定到這個(gè)鉤子上面,。
首先,你需要找到你要用的“鉤子”,,你需要瀏覽 WordPress 官方的Filter Reference和Action Reference文檔,,里面是長(zhǎng)長(zhǎng)的“鉤子”列表,,看一下下面的說(shuō)明,,然后找到對(duì)應(yīng)的“鉤子”就可以開(kāi)始使用了。比較常用的“鉤子”已經(jīng)給出官方文檔和使用說(shuō)明了,,例如:wp_insert_post_data,,不過(guò)由于列表太長(zhǎng)了,大部分的沒(méi)有給出很詳細(xì)的使用說(shuō)明,,就需要你按照經(jīng)驗(yàn)來(lái)使用,。
找到需要的“鉤子”之后,使用add_filter函數(shù)(具體用法可以看一下官方文檔:add filter)將鉤子和處理函數(shù)進(jìn)行掛鉤函數(shù)用法如下:
add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1);
就本例而言,,基本結(jié)構(gòu)如下:
<?phpfunction wpjam_insert_post_data( $data , $postarr ) { // 處理函數(shù)的邏輯部分和功能代碼 return $data;}add_filter( 'wp_insert_post_data', 'wpjam_insert_post_data', '99', 2 );?>
這樣,,我們的第一個(gè)步驟就完成了。下面來(lái)編寫(xiě)函數(shù)的處理代碼,。既然要過(guò)濾文章中的具有某些特征的代碼,,所以需要使用 PHP 的正則匹配替換掉??梢允褂萌缦碌?PHP 代碼:
$date = preg_replace('/<([a-z]+?)\s+?.*?>/i', '<$1>', $date);
根據(jù)wp_insert_post_data文檔可以看出,,傳遞進(jìn)去的$data數(shù)組里面是文章的相關(guān)信息,我們需要處理的是正文內(nèi)容,,所以使用$date[‘post_content’]和$date[‘post_content_filtered’]這兩個(gè)變量,,那么就可以寫(xiě)出下面這段代碼:
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 );
因?yàn)楹瘮?shù)里面已經(jīng)將處理后的數(shù)據(jù)return了,這樣第二步和第三步就完成了,,我們的這個(gè)需求也就實(shí)現(xiàn)了,。
總結(jié)
正是因?yàn)橛辛诉@種開(kāi)發(fā)機(jī)制,WordPress 的靈活性和擴(kuò)展性大大增強(qiáng),。如果你還想對(duì)文章進(jìn)行其他處理(例如文章末尾加版權(quán)信息等),,都可以繼續(xù)編寫(xiě)函數(shù),,掛鉤在對(duì)應(yīng)的鉤子即可。
注:原文作者于江水.