iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
WordPress

從 0 到 100:WordPress 開發者的實戰手冊系列 第 27

Day 27 - 外掛設計實戰 (3) 使用 Settings API 製作設定頁面

  • 分享至 

  • xImage
  •  

身為 WordPress 的使用者,自然會安裝、使用各式各樣的外掛。安裝完成後,第一件事情我們往往會做的就是尋找其設定頁面,翻閱各個設定選項,以確保每個功能和顯示效果都能符合我們的需求和期待。

無論是調整網站的外觀、設定功能還是管理內容,一個直觀且功能齊全的設定頁面總是能夠提供更好的使用者體驗哦!

自行設計設定頁面

我們可以從零開始設計 HTML 表單、自定義 CSS 來打造屬於我們自己外掛品牌的的設定頁面。

自行設計設定頁面的空白頁面
圖:自行設計設定頁面的空白頁面

利用昨天在文章中分享的 add_menu_page、add_options_page 等函式,可以輕鬆地畫出如上的空白頁面。

不過這就和網頁設計不使用任何框架一樣,需要花費較多時間在調整設定表單的外觀上,以及後續的表單處理。

設定頁面至儲存設定流程
圖:設定頁面至儲存設定流程

自行設計外掛的設定頁面可以依循以下步驟:

  1. add_options_page 產生設定頁面
    在昨天的文章介紹了這個函式的詳細用法,它在最上層選單「設定」下產生一個子選單連結,並連往設定頁面的。此函式的幾個參數:頁面標題、選單標題、使用權限、選單的網址 slug,以及渲染出設定頁面內容的回呼函式(見步驟 3)。
  2. get_option 讀取設定
    WordPress Options API 系列函式之一,get_option 用於從 wp_options 資料表中獲取外掛的設定。當使用者進入設定頁面時,通常會使用此函式來讀取目前的外掛的設定值,以便在表單中的欄位作為預設值來顯示它們。
  3. 回呼函式畫出設定表單
    此處的回呼函式通常是一個生成 HTML 表單的函數,表單包含了外掛設定的所有可用選項。這些選項應該預先在步驟 2 時使用 get_option 讀取設定值後填入,以表示目前的設定值為何。
  4. 送出表單
    一旦使用者完成表單的填寫並點擊送出表單按鈕,表單的資料將通過 POST 請求發送到伺服器。通常,設定頁的表單會發送回相同的設定頁面,但是 POST 請求會被處理,以儲存更新的設定值。
  5. 處理表單請求
    在使用者送出表單後,我們必須編寫一段程式邏輯來處理表單資料包括:
    • 檢查 nonce 有效性,以防止 CSRF、XSS 攻擊。
    • 驗證輸入值的合法性。
    • 檢查使用者的權限。
    • 清理 (sanitize)、過濾資料確保存到資料庫的資料正確及安全。
  6. update_option 儲存設定
    最後,再使用 update_option 函式來把資料更新到資料庫中。

使用 Settings API

另一個選擇是使用 WordPress 核心提供的 Settings API。這是一個開發者可以用來建立設定頁面的 API,不需要自己設計 HTML 和 CSS,它會產生和 WordPress 後台管理介面一致風格的設定表單。

函式一覽

名稱 功能類型 說明
add_settings_section 設定 建立一個新的設定區塊
add_settings_field 設定 在一個設定區塊中新增一個新的設定欄位
register_setting 設定 註冊一個新的設定,並可指定資料驗證和清理的回呼函式
unregister_setting 設定 取消註冊一個設定
settings_fields 表單輸出 輸出與註冊的設定相關的隱藏表單輸入欄位
do_settings_sections 表單輸出 輸出設定區塊和所有的設定欄位
do_settings_fields 表單輸出 輸出給定區塊的所有設定欄位
add_settings_error 顯示訊息 新增一個新的設定錯誤或更新的訊息
get_settings_errors 顯示訊息 獲取設定錯誤或更新訊息的陣列
settings_errors 顯示訊息 顯示設定錯誤或更新的訊息

雖然我們可以完全不使用 Settings API 來建立設定頁面,但使用它有以下優點:

  1. 畫面的一致性
    由於 Settings API 自動產生頁面的 HTML 區塊以及使用內建的 CSS,畫面的風格會和 WordPress 的後台管理區域的其它頁面有高度的一致性。
  2. 功能的維護性
    未來 WordPress 的更新不會破壞到頁面風格,因為 Settings API 由官方維護,每一次升級版本都在測試的驗收範圍內,也避免新加入或修改的內建 CSS 與自定義的 CSS 產生衝突。
  3. 省時省力
    在自行設計外掛的設定頁面的步驟 5 至 7,都被 Setttings API 幫忙處理了,不用另外處理 POST 請求、nonce 驗證以及過濾清理資料等等。

函式:add_settings_section

add_settings_section($id, $title, $callback, $page )

此函式用於向設定頁面加入新的設定區段。這個函式主要功能是提供一個讓開發者能夠在設定頁面上分組、安排相關的設定選項。

參數說明

  • $id (string) (必填):區段的 ID。之後在加入設定欄位到這個區段時,會用到這個 ID 來建立關聯。
  • $title (string) (必填):顯示在管理介面的區段標題。
  • $callback (callable) (必填):用來渲染區段內容的回呼函式。它可以輸出區段的描述或其他內容。
  • $page (string) (必填):與設定相關的設定頁面的選單 slug。這個值和 add_options_page 函數的 slug 相同,如果不相同的話,則不會出現在頁面上喔。

範例

add_settings_section 示範程式碼
圖:add_settings_section 示範程式碼

第 4 行至第 6 行:顯示說明文字的回呼函式。
第 12 行:使用 add_settings_section 函式加入一個區段到設定頁。
第 13 行:這個區段的 ID。
第 14 行:這個區段的標題。
第 15 行:這個區段用來顯示說明文字的回呼函式。也可以使用 HTML。
第 16 行:這是選單的 slug,用來指定設定頁。
第 20 行:註冊到 admin_init 鉤點。

但其實只加這樣還不會出現在後台設定頁面哦!還需要使用 do_settings_sections 函式把它印出來。

函式:do_settings_sections

do_settings_sections( $page )

參數說明

  • $page (string) (必填):設定頁面的 slug。與在 add_settings_section 函式定義的 page 參數相同。

範例

do_settings_sections 示範程式碼
圖:do_settings_sections 示範程式碼

第 4 行至第 19 行:這是我們註冊在 add_options_page 函式中的回呼函式。
第 13 行:為此頁面生成隱藏的 input 放置表單必須的參數,例如安全驗證用的 nonce,稍候會介紹此函式的用法。
第 14 行:使用 do_settings_sections 將前一段程式碼的結果給輸出到網頁上。
第 15 行:生成一個送出表單的按紐。

結果

顯示區段在設定頁面上
圖:顯示區段在設定頁面上

這個結果頁面示範了利用 add_settings_section 函式新增區段,再用 do_settings_sections 函式將它輸出到網頁上。

函式:settings_fields

settings_fields($option_group )

用於輸出設定頁面表單的隱藏欄位的函式,幫助處理安全性和設定頁面的字串輸出,例如驗證所需要的 nonce 值。

參數說明

  • $option_group (string) (必填):設定組的名稱。這個設定字串應該 register_setting 函式中用到的設定組名稱相同。

範例

查看頁面原始碼
圖:查看頁面原始碼

在前面的範例網頁中,打開原始碼查看,settings_fields 函式插入了如上圖的隱藏欄位到網頁中,主要為安全目的。

函式:add_settings_field

add_settings_field($id, $title, $callback, $page, $section, $args );

當 add_settings_section 函式定義好一個設定區段後,再使用此函式在該區段內,新增一個設定欄位。該欄位可以是一個文字框、核取方塊、選擇欄、按鈕等等。

參數說明

  • $id (string) (必填):用於識別設定欄位的唯一ID,這個 ID 也用作欄位的名稱。
  • $title (string) (必填):將在設定頁面上顯示為欄位的標題或名稱。
  • $callback (callable) (必填):用於渲染欄位的回呼函式。用來顯示設定欄位 的 HTML。
  • $page (string) (必填):該欄位所屬的設定頁面的 slug,這個 slug 應該與建立頁面時add_options_page 函式或其他類似函式中定義的 slug 相匹配。
  • $section (string) (必填):該欄位所屬的設定區段的 ID,該 ID 應與add_settings_section 函式中定義的區段 ID 相匹配。
  • $args (array):一個可選的參數,這個陣列可以包含其他的選項,例如欄位的描述或預設值等。

範例

add_settings_field 示範程式碼
圖:add_settings_field 示範程式碼

基於前段程式碼再加上一些使用此函式的範例。

第 27 行:使用 add_settings_field 函式。
第 28 行:欄位的 ID。
第 29 行:欄位的標題名稱。
第 30 行:回呼函式,印出該欄位的 HTML。
第 31 行:頁面的 ID,與 add_settings_section 設定的相同。
第 32 行:區段的 ID,與 add_settings_section 設定的相同。

結果

顯示設定欄位在設定頁面上
圖:顯示設定欄位在設定頁面上

函式:do_settings_fields

do_settings_fields( string $page, string $section );

此函式可以指定渲染設定於某個區段上的所有設定欄位。

這個函式一般來說不會和另一個函式 do_settings_sections 混用,絕大部分的情境例如只有一頁的設定,使用 do_settings_sections 函式就能滿足了。

會用到 do_settings_fields 函式的情況,通常是為了做成頁籤式的設定頁面,才需要指定區段的 ID 來進行顯示,例如,不同的區段 ID 各佔一個頁籤頁面來顯示。

參數說明

  • $page (string):頁面的 slug,這個值應該與 add_settings_section 函式或 add_settings_field 函式的 $page 參數相對應。

  • $section (string):設定區段的 ID,這個值應該與 add_settings_section 函式中用於標記你要顯示區段的 $id 參數相對應。

通常情況下,多數開發者會選擇使用 do_settings_sections 函式來一次性輸出頁面上的所有區段和欄位,除非你有特殊的需求要單獨控制每個區段的輸出。

函式:register_setting

register_setting($option_group, $option_name, $args);

參數說明

  • $option_group (string) (必填):設定選項群組。

  • $option_name (string) (必填):設定選項的名稱。這是存在 wp_options 資料表中的鍵名。

  • $args (array):可選,可以包括:

參數名稱 型別 說明 Example Values
type string 資料類型。 string, boolean, integer, number
description string 選項說明。
sanitize_callback callable 進行清理過濾的回呼函式。
show_in_rest bool 是否在 REST API 中顯示設定。 true, false
default mixed 使用 get_option 函式找不到資料時會取得的預設值。

範例

register_setting示範程式碼
圖:register_setting 示範程式碼

第 5 行:使用 register_setting 函式註冊一個設定選項。
第 6 行:這個參數必須和 settings_fields 函式的 option_group 參數相同,這樣送出表單後才能通過安全驗證。
第 7 行:設定選項的名稱,也就是 wp_options 資料表的鍵名,必須和表單內的 input 對應的 name 相同,WordPress 才抓的到資料來存放設定。
第 9 行:指定型別。
第 10 行:過濾、清理輸入的值所用的回呼函式,可以自己寫,不過這邊筆者用的是內建的函式進行清理。

結果

送出表單
動圖:送出表單

總結

今天的文章雖然推薦使用 Settings API,不過如果有更強烈的動機想要打造獨特的、品牌性高的設定頁面,只要特別注意在安全性的檢查、輸入字串的清理都有踏實的處理,那麼也是很不錯的選擇哦。

在印出表單的函式,do_settings_sections 與 do_settings_fields 取其一,避免混用造成混淆。想要設計成頁籤式,指定不同區段的設定欄位至不同頁籤,可使用 do_settings_fields 函式來達成。

另外,必須先使用 register_setting 函式來註冊設定欄位,在 HTML 中同名的 input 輸入才能順利儲存到資料表唷。


課後思考:

WordPress Settings API 雖然好用,但試著找出它的缺點,你覺得它的缺點是什麼呢?

前篇解答參考:

我們可以採用 add_submenu_page 這個函式來將子選單放到自訂文章類型底下。例如商品的 slug 是 product,那麼第一參數的 $parent_slugedit.php?post_type=product,這樣就能放到「商品」之下了。


上一篇
Day 26 - 外掛設計實戰 (2) 建立選單入口與設定頁面
下一篇
Day 28 - 外掛設計實戰 (4) 設計文章編輯頁的額外資訊區域
系列文
從 0 到 100:WordPress 開發者的實戰手冊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言