在文章管理頁面上,提供一個區塊 UI,讓使用者可以輸入資料,跟隨著儲存文章的動作一起把外掛提供的功能設定資料送進 wp_postmeta 資料表,這類 UI 在 WordPress 中稱為額外資訊區域 (Meatabox)。
昨天的文章提到的外掛設定頁面可以完全自己設計,也可以使用 WordPress 核心提供的 Settings API 讓外掛開發者可以少做一些事、更省時省力。
同樣地,在文章管理頁面,要設計額外資訊區域,也可以完成自己來,或者使用 WordPress 核心已經提供的 add_meta_box
函式來讓我們少做一些事。
雖然主角是 add_meta_box 函式,不過整個流程需要編寫幾個自訂函式並註冊到相關的鉤點中。
名稱 | 說明 |
---|---|
add_meta_boxes | 這個鉤點讓開發者向 WordPress 後台的文章編輯畫面新增自定義的 Metabox。 |
save_post | save_post 是在 WordPress 保存文章到資料庫後觸發的鉤點。這個鉤點允許開發者在文章儲存時執行額外的動作,例如儲存 Metabox 的資料、清除快取等。 |
admin_enqueue_scripts | admin_enqueue_scripts 鉤點是用於在 WordPress 管理後台載入自定義的 JavaScript 檔案和 CSS 樣式檔案的標準方法。 |
除了自定義的額外資訊區域內的表單 HTML,我們還需要引入 JavaScript(檢查字數是否符合 SEO 建議)。雖然 Metabox 已經是原生的 UI,但表單的外觀細節,還需要引入 CSS 檔案來美化,排版才好看。
add_meta_box($id, $title, $callback, $screen, $context, $priority , $callback_args);
使用此函式將額外資訊區域加到編輯畫面。
參數說明
$id
(string)(必填):ID。$title
(string)(必填):標題文字。$callback
(callable)(必填):渲染內容的回呼函式。$screen
(string|array|WP_Screen):應該顯示 Metabox 的編輯畫面。它可以是一個螢幕 ID、螢幕基本物件、或螢幕 ID 的陣列。$context
(string):Metabox 應該顯示在哪個區域。可選值包括 normal
、side
、和 advanced
。$priority
(string):Metabox 在頁面中的優先級。可選值包括 high
、sorted
、和low
。$callback_args
(array):回呼函式的參數陣列。所有以下範例程式碼的 Gist。
圖:示範使用 add_meta_box 函式程式碼
第 5 行:使用 add_meta_box 函式。
第 6 行:定義此 Metabox 的 ID。
第 7 行:定義此 Metabox 的標題文字,顯示在額外資訊區域上的標題。
第 8 行:要進行渲染內容的回呼函式。
第 9 行:顯示在 post。
第 10 行:顯示在一般位置,normal 是頁面下方。
第 11 行:排序採用預設值。
第 15 行:註冊到 add_meta_boxes
鉤點。
圖:渲染內容的回呼函式程式碼
第 7 行:產生 nonce 的欄位。
第 8 行:讀取標題的資料。
第 9 行:讀取描述的資料。
第 18 行及第 33 行:這裡是 JS 程式碼來顯示目前輸入字元數,以及偵測到超過寬度或字數會變紅色。
第 24 行:標題的輸入框。
第 39 行:描述的輸入框。
註:我們定義的 postmeta 的 key,名稱開頭加底線
_
,是 WordPress 用來隱藏不顯示在管理頁面的欄位,這樣使用者才不會自行修改原始值。
圖:載入 JS 及 CSS 的範例程式碼
第 7 行到第 8 行:限制只有新增文章及編輯文章的管理頁面才載入。
第 14 行:註冊 CSS 樣式檔案。
第 15 行:載入 CSS 樣式檔案。
第 17 行:註冊 JavaScript 檔案。
第 18 行:載入 JavaScript 檔案。
第 21 行:註冊到 admin_equeue_scripts
鉤點,以輸出到網頁上。
圖:CSS 語法
稍微調整一個表單元件的間距。
動圖:查看底部的額外資訊區域
到目前為止的步驟,可以可以看到底部的額外資訊區域,有著基本的 UI 在那裡了。
圖:JavaScript 程式碼
第 2 行到第 4 行:如果網頁上沒找到我們的額外資訊區域的 ID,則略過不執行。
第 6 行:Google 搜尋的標題建議字元數,目前為 60 個字元。
第 7 行:Google 搜尋的標題建議寬度像素,目前為 600 px。由於中文字約 2-3 個英文字元的像素寬度,一般來說檢查字元會不準確,主要以像素寬度作為檢查要點。
第 8 行:Google 搜尋的描述建議字元數,目前為 160 個字元。
第 7 行:Google 搜尋的描述建議寬度像素,目前為 920 px (電腦版)。
第 11 至 17 行定義的 getTextWidth
它的任務就是利用 HTML5 的 convas 來幫我們算出像素寬度。
第 24 至 33 行:監聽標題的輸入,檢查字數及像素寬度。
第 35 至 44 行:監聽描述的輸入,檢查字數及像素寬度。
動圖:測試一下輸入檢查
字數僅供參考,主要是計算字元的總像素長度,超過建議值就會變成紅色來提醒使用者。
圖:儲存設定的程式碼
第 8 行:檢查有無 nonce 的輸入。
第 9 行:用 current_user_can
函式來檢查使用者是否有編輯此文章的權限。
如果以上都沒有通過,則略過不儲存。
第 14 行:這邊使用兩個函式來進行過濾輸入的值。如果有裝 PHPCS 自動檢查程式碼,VSCode 編輯器為自動提示,任何輸入都要進行過濾。
第 16 行:驗證 nonce 是否有效。如果無效,則略過不儲存。
第 20 至 27 行:先進行輸入字串的清理,去除頭尾可能會有的空白字元,再進儲存標題及描述。
最後,在第 31 行,將此函式註冊到 save_post
鉤點中,當使用者儲存編輯文章時,就會執行此函式。
透過 add_meta_box
函式讓我們很容易地在文章管理頁面產生額外資訊區域,無論是在頁面底部還是在右側邊欄,都可以。
老生常談的一點,由於輸入的部分是由開發者自行處理,我們必須在每一個輸入都使用清理、過濾的函式,並檢查權限及 nonce 有效性,把外掛安全性的基本動作做好。畢竟是開放原始碼的東西,放到網路上,有心人士使用腳本掃描,發現有可趁之機,危害的是相信開發者的使用者們。
課後思考:
為什麼 JS 及 CSS 檔案要限制使用頁面載入,有什麼考量?
前篇解答參考:
Settings API 每一個欄位都對應到一個 wp_options 資料表的行數,越多設定選項,產生越多。每新增一個欄位,必須盤點用到的選項,並加入在移除外掛時的垃圾回收機制內,畢竟不是每一個使用者都會喜歡使用我們的外掛,很多使用者只是試用看看。當使用者反安裝時,不要留垃圾在人家的網站上哦。