本篇文章更新時間:2026/03/03
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知或向一介資男的 LINE 社群反應。
如果本站內容對你有幫助,歡迎贊助支持 。
本系列文參考自 WordPress.org 官方外掛開發文件 - Settings 的繁體中文版本,並加入作者實務開發經驗補充。
WordPress Settings API 是外掛開發中處理設定頁面的標準化解決方案。當你的外掛需要讓使用者自訂行為參數時,Settings API 提供了一套完整的機制來註冊設定欄位、產生表單、驗證資料,並自動處理儲存流程。搭配 Options API 來管理鍵值資料的存取,開發者可以快速建立安全、符合 WordPress 規範的設定頁面,而不需要自行處理表單提交、nonce 驗證和資料庫操作等繁瑣細節。
Options API 基礎
在深入 Settings API 之前,我們先來了解 Options API。Options API 是 WordPress 用來儲存與讀取鍵值對(key-value pair)資料的底層機制,它將資料存放在資料庫的 wp_options 資料表中。外掛的設定值最終都是透過 Options API 來存取的,Settings API 則是在它之上提供了表單化的操作介面。
get_option() - 讀取設定值
get_option() 用來從資料庫讀取指定的選項值。它接受兩個參數:選項名稱和預設值。
// 基本用法:讀取一個選項值
$value = get_option( 'my_plugin_api_key' );
// 指定預設值:當選項不存在時回傳預設值
$is_enabled = get_option( 'my_plugin_enabled', false );
// 讀取陣列型態的選項
$settings = get_option( 'my_plugin_settings', array(
'api_key' => '',
'cache_time' => 3600,
'debug_mode' => false,
) );
當選項不存在於資料庫中時,如果未指定預設值,get_option() 會回傳 false。建議在呼叫時都提供合理的預設值,以避免因為外掛尚未儲存過設定而產生錯誤。
update_option() - 新增或更新設定值
update_option() 用來新增或更新一個選項值。如果選項已存在,它會更新為新的值;如果不存在,則會自動建立。
// 更新單一值
update_option( 'my_plugin_api_key', 'sk-abc123def456' );
// 更新布林值
update_option( 'my_plugin_enabled', true );
// 儲存陣列
update_option( 'my_plugin_settings', array(
'api_key' => 'sk-abc123def456',
'cache_time' => 7200,
'debug_mode' => true,
) );
// 第三個參數控制是否自動載入(autoload)
// 設為 false 可減少記憶體消耗,適合不常使用或資料量大的選項
update_option( 'my_plugin_large_data', $large_array, false );
update_option() 的第三個參數 $autoload 值得特別注意。WordPress 在每次頁面載入時,會將所有 autoload 設為 'yes' 的選項一次性從資料庫載入到記憶體中。對於經常使用的小型設定值,autoload 是好的;但如果你的外掛儲存了大量資料(例如快取資料或日誌記錄),應該將 autoload 設為 false,以免拖慢整個網站的效能。
delete_option() - 刪除設定值
delete_option() 用來從資料庫中移除指定的選項。這通常在外掛解除安裝(uninstall)時使用,用來清理外掛產生的資料。
// 刪除單一選項
delete_option( 'my_plugin_api_key' );
// 在 uninstall.php 中清理所有外掛選項
delete_option( 'my_plugin_settings' );
delete_option( 'my_plugin_enabled' );
delete_option( 'my_plugin_version' );
良好的外掛應該在解除安裝時清理自己產生的所有資料庫記錄。你可以在外掛的 uninstall.php 檔案中,或者透過 register_uninstall_hook() 來執行清理工作。關於外掛的啟用與解除安裝流程,可以參考外掛基礎知識中的說明。
將多個設定值合併為單一選項
在實務開發中,建議將外掛的多個設定值儲存為單一陣列選項,而非每個設定值各自獨立一筆記錄。這樣做有幾個好處:減少資料庫查詢次數、降低與其他外掛的命名衝突風險,以及方便統一管理。
// 推薦:使用單一選項儲存所有設定
$defaults = array(
'api_key' => '',
'cache_time' => 3600,
'debug_mode' => false,
'log_level' => 'error',
);
// 讀取時合併預設值,確保所有鍵都存在
$settings = wp_parse_args( get_option( 'my_plugin_settings', array() ), $defaults );
// 使用個別設定值
$api_key = $settings['api_key'];
$cache_time = $settings['cache_time'];
wp_parse_args() 是這個模式中的關鍵函式。它會將使用者儲存的設定與預設值合併,確保即使使用者從未修改過某個設定,程式也能取得合理的預設值。當你在未來版本中新增了新的設定欄位時,既有使用者的設定不會因此出錯。
Settings API 介紹
Settings API 是 WordPress 提供的一組函式,用來標準化外掛設定頁面的建立流程。它處理了表單的產生、nonce 安全驗證、資料的儲存,以及設定值的驗證(sanitization)。使用 Settings API 的最大好處是:你不需要自行處理 $_POST 資料、不需要手動呼叫 update_option()、不需要自行產生 nonce 欄位,這些都由 WordPress 核心幫你處理。
register_setting() - 註冊設定
register_setting() 是 Settings API 的核心函式,用來在 WordPress 中註冊一個設定選項。它必須在 admin_init 這個 Action Hook 中呼叫。
register_setting(
string $option_group, // 設定群組名稱,對應 settings_fields() 的參數
string $option_name, // 選項名稱,對應 wp_options 資料表中的 option_name
array $args = array() // 額外參數
);
$args 陣列可以包含以下參數:
- type(字串):選項值的資料類型,可以是
string、boolean、integer、number、array或object。 - description(字串):選項的描述文字,主要用於 REST API 的 schema。
- sanitize_callback(回呼函式):在儲存前對設定值進行驗證與清理的函式。這是確保資料安全的重要環節。
- show_in_rest(布林值):是否在 WordPress REST API 中公開此設定。預設為
false。 - default(混合型別):選項的預設值。當
get_option()找不到資料時會使用此值。
add_action( 'admin_init', 'wporg_settings_init' );
function wporg_settings_init() {
register_setting(
'wporg_options', // 設定群組
'wporg_settings', // 選項名稱
array(
'type' => 'array',
'sanitize_callback' => 'wporg_sanitize_settings',
'default' => array(
'api_key' => '',
'cache_time' => 3600,
),
)
);
}
add_settings_section() - 新增設定區段
設定區段(Section)用來將多個相關的設定欄位組織在一起。每個區段可以有自己的標題和說明文字。
add_settings_section(
string $id, // 區段的唯一識別碼
string $title, // 區段的標題
callable $callback, // 輸出區段說明文字的回呼函式
string $page // 此區段要顯示在哪個設定頁面(對應選單的 slug)
);
add_settings_section(
'wporg_general_section', // 區段 ID
'一般設定', // 區段標題
'wporg_general_section_callback', // 回呼函式
'wporg' // 頁面 slug
);
function wporg_general_section_callback() {
echo '<p>在這裡設定外掛的基本參數。</p>';
}
add_settings_field() - 新增設定欄位
設定欄位(Field)是使用者實際操作的表單元素,每個欄位都必須屬於某個區段。
add_settings_field(
string $id, // 欄位的唯一識別碼
string $title, // 欄位的標籤文字
callable $callback, // 輸出欄位 HTML 的回呼函式
string $page, // 此欄位要顯示在哪個設定頁面
string $section, // 此欄位屬於哪個區段
array $args // 傳遞給回呼函式的額外參數
);
add_settings_field(
'wporg_api_key', // 欄位 ID
'API 金鑰', // 欄位標籤
'wporg_api_key_field_callback', // 回呼函式
'wporg', // 頁面 slug
'wporg_general_section', // 所屬區段
array(
'label_for' => 'wporg_api_key', // 讓標籤可以點擊聚焦到輸入欄位
'class' => 'wporg-row', // 自訂 CSS 類別
)
);
function wporg_api_key_field_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<input type="text"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[api_key]"
value="<?php echo esc_attr( $settings['api_key'] ?? '' ); ?>"
class="regular-text">
<p class="description">
請輸入從服務供應商取得的 API 金鑰。
</p>
<?php
}
注意 name 屬性的格式:wporg_settings[api_key]。因為我們在 register_setting() 中註冊的選項名稱是 wporg_settings,所以每個欄位的 name 都必須是 wporg_settings[鍵名] 的格式,這樣 WordPress 才能正確地將表單資料組合成陣列並儲存到對應的選項中。
settings_fields() 與 do_settings_sections()
這兩個函式是在設定頁面的表單中使用的輸出函式:
- settings_fields( $option_group ):輸出隱藏的表單欄位,包含 nonce 安全驗證碼和
action欄位。它的參數必須與register_setting()中的$option_group一致。 - do_settings_sections( $page ):輸出所有註冊到指定頁面的區段與欄位。它的參數是設定頁面的 slug,必須與
add_settings_section()中的$page一致。
// 在表單中使用
<form action="options.php" method="post">
<?php
// 輸出 nonce 和 action 欄位
settings_fields( 'wporg_options' );
// 輸出所有區段和欄位
do_settings_sections( 'wporg' );
// 輸出送出按鈕
submit_button( '儲存設定' );
?>
</form>
表單的 action 屬性必須指向 options.php,這是 WordPress 內建的設定儲存處理程式。它會自動處理 nonce 驗證、權限檢查、呼叫 sanitize_callback 清理資料,然後將資料儲存到 wp_options 資料表中。
建立完整的設定頁面
現在我們將管理選單、Settings API 與 Options API 三者結合,建立一個完整、可運作的外掛設定頁面。這個範例包含了多種常見的表單欄位類型,並展示了資料驗證的最佳實踐。
步驟一:註冊管理選單
首先,我們需要在 WordPress 後台建立一個設定頁面的選單入口。這裡我們使用 add_options_page() 將設定頁面加入到「設定」選單下,這是官方推薦的做法。關於管理選單的詳細說明,請參考管理選單開發教學。
/**
* 在「設定」選單下新增外掛設定頁面
*/
add_action( 'admin_menu', 'wporg_options_page' );
function wporg_options_page() {
add_options_page(
'WPOrg 外掛設定', // 頁面標題
'WPOrg 設定', // 選單名稱
'manage_options', // 所需權限
'wporg', // 選單 slug
'wporg_options_page_html' // 回呼函式
);
}
步驟二:註冊設定與欄位
接著在 admin_init Hook 中註冊設定選項、區段和欄位。這個範例示範了文字輸入、數字輸入、核取方塊和下拉選單四種常見的欄位類型。
/**
* 註冊設定選項、區段和欄位
*/
add_action( 'admin_init', 'wporg_settings_init' );
function wporg_settings_init() {
// 註冊設定,指定驗證回呼函式
register_setting(
'wporg_options',
'wporg_settings',
array(
'type' => 'array',
'sanitize_callback' => 'wporg_sanitize_settings',
'default' => array(
'api_key' => '',
'cache_time' => 3600,
'debug_mode' => false,
'log_level' => 'error',
),
)
);
// 新增「一般設定」區段
add_settings_section(
'wporg_general_section',
'一般設定',
'wporg_general_section_callback',
'wporg'
);
// 新增「進階設定」區段
add_settings_section(
'wporg_advanced_section',
'進階設定',
'wporg_advanced_section_callback',
'wporg'
);
// API 金鑰欄位(文字輸入)
add_settings_field(
'wporg_api_key',
'API 金鑰',
'wporg_api_key_callback',
'wporg',
'wporg_general_section',
array( 'label_for' => 'wporg_api_key' )
);
// 快取時間欄位(數字輸入)
add_settings_field(
'wporg_cache_time',
'快取時間(秒)',
'wporg_cache_time_callback',
'wporg',
'wporg_general_section',
array( 'label_for' => 'wporg_cache_time' )
);
// 除錯模式欄位(核取方塊)
add_settings_field(
'wporg_debug_mode',
'除錯模式',
'wporg_debug_mode_callback',
'wporg',
'wporg_advanced_section',
array( 'label_for' => 'wporg_debug_mode' )
);
// 日誌等級欄位(下拉選單)
add_settings_field(
'wporg_log_level',
'日誌等級',
'wporg_log_level_callback',
'wporg',
'wporg_advanced_section',
array( 'label_for' => 'wporg_log_level' )
);
}
步驟三:實作區段與欄位的回呼函式
每個區段和欄位都需要一個回呼函式來輸出對應的 HTML。以下是各個回呼函式的實作。
/**
* 區段回呼函式
*/
function wporg_general_section_callback() {
echo '<p>設定外掛的基本運作參數。</p>';
}
function wporg_advanced_section_callback() {
echo '<p>進階設定適用於開發與除錯用途,一般使用者通常不需要修改這些選項。</p>';
}
/**
* API 金鑰欄位(文字輸入)
*/
function wporg_api_key_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<input type="text"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[api_key]"
value="<?php echo esc_attr( $settings['api_key'] ?? '' ); ?>"
class="regular-text">
<p class="description">
請輸入從服務供應商取得的 API 金鑰。
</p>
<?php
}
/**
* 快取時間欄位(數字輸入)
*/
function wporg_cache_time_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<input type="number"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[cache_time]"
value="<?php echo esc_attr( $settings['cache_time'] ?? 3600 ); ?>"
min="0"
max="86400"
step="60"
class="small-text">
<p class="description">
資料快取的有效時間,單位為秒。設為 0 表示不快取。預設值為 3600 秒(1 小時)。
</p>
<?php
}
/**
* 除錯模式欄位(核取方塊)
*/
function wporg_debug_mode_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<label for="<?php echo esc_attr( $args['label_for'] ); ?>">
<input type="checkbox"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[debug_mode]"
value="1"
<?php checked( ! empty( $settings['debug_mode'] ) ); ?>>
啟用除錯模式(會在日誌中記錄詳細的執行資訊)
</label>
<?php
}
/**
* 日誌等級欄位(下拉選單)
*/
function wporg_log_level_callback( $args ) {
$settings = get_option( 'wporg_settings' );
$current = $settings['log_level'] ?? 'error';
$levels = array(
'debug' => 'Debug(除錯)',
'info' => 'Info(資訊)',
'warning' => 'Warning(警告)',
'error' => 'Error(錯誤)',
);
?>
<select id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[log_level]">
<?php foreach ( $levels as $value => $label ) : ?>
<option value="<?php echo esc_attr( $value ); ?>"
<?php selected( $current, $value ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
<p class="description">
選擇要記錄的日誌等級。等級越低,記錄的資訊越詳細。
</p>
<?php
}
步驟四:實作資料驗證(Sanitize Callback)
資料驗證是設定頁面中最重要的安全環節之一。sanitize_callback 會在 WordPress 將資料寫入資料庫之前被自動呼叫,你必須在這裡檢查每一個欄位的值是否合法,並清理任何不安全的內容。
/**
* 驗證並清理設定值
*
* @param array $input 使用者提交的表單資料
* @return array 清理後的資料
*/
function wporg_sanitize_settings( $input ) {
$sanitized = array();
// API 金鑰:清理文字,只保留英數字和連字號
if ( isset( $input['api_key'] ) ) {
$sanitized['api_key'] = sanitize_text_field( $input['api_key'] );
}
// 快取時間:確保是 0 到 86400 之間的整數
if ( isset( $input['cache_time'] ) ) {
$cache_time = absint( $input['cache_time'] );
$sanitized['cache_time'] = min( $cache_time, 86400 );
}
// 除錯模式:轉為布林值
$sanitized['debug_mode'] = ! empty( $input['debug_mode'] );
// 日誌等級:確保是允許的值之一
$valid_levels = array( 'debug', 'info', 'warning', 'error' );
if ( isset( $input['log_level'] ) && in_array( $input['log_level'], $valid_levels, true ) ) {
$sanitized['log_level'] = $input['log_level'];
} else {
$sanitized['log_level'] = 'error'; // 預設值
}
return $sanitized;
}
在驗證函式中,有幾個重要的原則:
- 文字欄位使用
sanitize_text_field()清除 HTML 標籤和多餘的空白。 - 數字欄位使用
absint()或intval()轉換為整數,並用min()/max()限制範圍。 - 核取方塊使用
! empty()轉為布林值,因為未勾選的核取方塊不會出現在$_POST資料中。 - 下拉選單和單選鈕使用白名單驗證(
in_array()),確保提交的值是預先定義的合法選項之一。
步驟五:輸出設定頁面 HTML
最後,我們實作管理頁面的回呼函式,將所有元素組合成完整的設定頁面。
/**
* 設定頁面的 HTML 輸出
*/
function wporg_options_page_html() {
// 檢查使用者權限
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// 顯示設定儲存成功的通知
if ( isset( $_GET['settings-updated'] ) ) {
add_settings_error(
'wporg_messages',
'wporg_message',
'設定已儲存。',
'updated'
);
}
// 輸出錯誤與通知訊息
settings_errors( 'wporg_messages' );
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form action="options.php" method="post">
<?php
// 輸出安全欄位(nonce、action、option_page)
settings_fields( 'wporg_options' );
// 輸出所有區段與欄位
do_settings_sections( 'wporg' );
// 輸出送出按鈕
submit_button( '儲存設定' );
?>
</form>
</div>
<?php
}
這個頁面結構的重點:
current_user_can():即使選單已有權限控制,在頁面輸出時再次檢查是良好的防禦性程式設計。settings_errors():顯示由add_settings_error()加入的通知訊息,包括成功儲存的提示和驗證錯誤。get_admin_page_title():動態取得頁面標題,而非硬編碼,這樣修改選單設定時不需要同步修改頁面內容。<div class="wrap">:WordPress 後台標準的頁面容器,確保樣式與其他後台頁面一致。
完整外掛程式碼
以下是將上述所有步驟整合成的完整外掛程式碼,你可以直接使用:
<?php
/**
* Plugin Name: WPOrg Settings Demo
* Description: 示範如何使用 WordPress Settings API 建立設定頁面
* Version: 1.0.0
* Author: Developer Name
* Text Domain: wporg-settings-demo
*/
// 防止直接存取
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* 在「設定」選單下新增外掛設定頁面
*/
add_action( 'admin_menu', 'wporg_options_page' );
function wporg_options_page() {
add_options_page(
'WPOrg 外掛設定',
'WPOrg 設定',
'manage_options',
'wporg',
'wporg_options_page_html'
);
}
/**
* 註冊設定選項、區段和欄位
*/
add_action( 'admin_init', 'wporg_settings_init' );
function wporg_settings_init() {
register_setting(
'wporg_options',
'wporg_settings',
array(
'type' => 'array',
'sanitize_callback' => 'wporg_sanitize_settings',
'default' => array(
'api_key' => '',
'cache_time' => 3600,
'debug_mode' => false,
'log_level' => 'error',
),
)
);
// 一般設定區段
add_settings_section(
'wporg_general_section',
'一般設定',
function() {
echo '<p>設定外掛的基本運作參數。</p>';
},
'wporg'
);
// 進階設定區段
add_settings_section(
'wporg_advanced_section',
'進階設定',
function() {
echo '<p>進階設定適用於開發與除錯用途。</p>';
},
'wporg'
);
// API 金鑰
add_settings_field(
'wporg_api_key',
'API 金鑰',
'wporg_api_key_callback',
'wporg',
'wporg_general_section',
array( 'label_for' => 'wporg_api_key' )
);
// 快取時間
add_settings_field(
'wporg_cache_time',
'快取時間(秒)',
'wporg_cache_time_callback',
'wporg',
'wporg_general_section',
array( 'label_for' => 'wporg_cache_time' )
);
// 除錯模式
add_settings_field(
'wporg_debug_mode',
'除錯模式',
'wporg_debug_mode_callback',
'wporg',
'wporg_advanced_section',
array( 'label_for' => 'wporg_debug_mode' )
);
// 日誌等級
add_settings_field(
'wporg_log_level',
'日誌等級',
'wporg_log_level_callback',
'wporg',
'wporg_advanced_section',
array( 'label_for' => 'wporg_log_level' )
);
}
/**
* 欄位回呼函式
*/
function wporg_api_key_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<input type="text"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[api_key]"
value="<?php echo esc_attr( $settings['api_key'] ?? '' ); ?>"
class="regular-text">
<p class="description">請輸入從服務供應商取得的 API 金鑰。</p>
<?php
}
function wporg_cache_time_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<input type="number"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[cache_time]"
value="<?php echo esc_attr( $settings['cache_time'] ?? 3600 ); ?>"
min="0" max="86400" step="60"
class="small-text">
<p class="description">
資料快取的有效時間,單位為秒。設為 0 表示不快取。
</p>
<?php
}
function wporg_debug_mode_callback( $args ) {
$settings = get_option( 'wporg_settings' );
?>
<label for="<?php echo esc_attr( $args['label_for'] ); ?>">
<input type="checkbox"
id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[debug_mode]"
value="1"
<?php checked( ! empty( $settings['debug_mode'] ) ); ?>>
啟用除錯模式
</label>
<?php
}
function wporg_log_level_callback( $args ) {
$settings = get_option( 'wporg_settings' );
$current = $settings['log_level'] ?? 'error';
$levels = array(
'debug' => 'Debug(除錯)',
'info' => 'Info(資訊)',
'warning' => 'Warning(警告)',
'error' => 'Error(錯誤)',
);
?>
<select id="<?php echo esc_attr( $args['label_for'] ); ?>"
name="wporg_settings[log_level]">
<?php foreach ( $levels as $value => $label ) : ?>
<option value="<?php echo esc_attr( $value ); ?>"
<?php selected( $current, $value ); ?>>
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
</select>
<p class="description">選擇要記錄的日誌等級。</p>
<?php
}
/**
* 驗證並清理設定值
*/
function wporg_sanitize_settings( $input ) {
$sanitized = array();
if ( isset( $input['api_key'] ) ) {
$sanitized['api_key'] = sanitize_text_field( $input['api_key'] );
}
if ( isset( $input['cache_time'] ) ) {
$sanitized['cache_time'] = min( absint( $input['cache_time'] ), 86400 );
}
$sanitized['debug_mode'] = ! empty( $input['debug_mode'] );
$valid_levels = array( 'debug', 'info', 'warning', 'error' );
if ( isset( $input['log_level'] ) && in_array( $input['log_level'], $valid_levels, true ) ) {
$sanitized['log_level'] = $input['log_level'];
} else {
$sanitized['log_level'] = 'error';
}
return $sanitized;
}
/**
* 設定頁面 HTML
*/
function wporg_options_page_html() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
if ( isset( $_GET['settings-updated'] ) ) {
add_settings_error(
'wporg_messages',
'wporg_message',
'設定已儲存。',
'updated'
);
}
settings_errors( 'wporg_messages' );
?>
<div class="wrap">
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields( 'wporg_options' );
do_settings_sections( 'wporg' );
submit_button( '儲存設定' );
?>
</form>
</div>
<?php
}
實務開發建議
作者實務經驗分享:
1. Settings API vs 自建表單的選擇:Settings API 最大的優勢是它幫你處理了 nonce 驗證、權限檢查和資料儲存這些繁瑣但重要的安全機制。對於標準的設定頁面,我強烈建議使用 Settings API。但如果你的表單需要複雜的互動邏輯(例如 AJAX 即時儲存、拖放排序、動態新增欄位等),Settings API 的制式結構可能反而成為限制,這時候自建表單會更靈活。自建表單時,務必自行處理好 nonce 驗證和資料清理,細節可以參考外掛開發安全性指南中的說明。
2. 使用 sanitize_callback 驗證設定值:不要忽略
sanitize_callback,這是你最後一道資料驗證防線。即使前端已經有了 JavaScript 驗證,使用者仍然可以透過瀏覽器開發者工具修改表單資料後提交。在sanitize_callback中,你可以使用add_settings_error()來顯示驗證錯誤訊息,讓使用者知道哪些欄位的值不合法。例如,當 API 金鑰格式不正確時,可以顯示「API 金鑰格式不正確,請重新輸入」的錯誤提示,並拒絕儲存該欄位的值。3. 將多個設定值合併為單一選項:如同前面 Options API 章節中提到的,將所有設定值存在同一個陣列選項中(例如
my_plugin_settings),而非每個欄位各自一個選項。這不僅減少了資料庫查詢,也讓你在register_setting()中只需要註冊一次,sanitize_callback也只需要一個函式就能處理所有欄位的驗證。4. 設定頁面與管理選單的搭配:如果你的外掛功能單純,只需要一個設定頁面,建議使用
add_options_page()將頁面加入到「設定」選單下,而不要另外建立頂層選單。只有當外掛需要多個管理頁面(例如設定頁、報表頁、日誌頁等)時,才考慮建立頂層選單。關於選單架構的設計原則,可以參考管理選單開發教學。5. 善用 WordPress 內建的 CSS 類別:在欄位回呼函式中,使用
regular-text、small-text、large-text等 WordPress 內建的 CSS 類別來控制輸入欄位的寬度,使用description類別來標示說明文字。這些類別能讓你的設定頁面自動與 WordPress 後台的視覺風格一致,不需要額外撰寫 CSS。
本文是「WordPress 外掛開發完整指南」系列的第 6 篇。
上一篇:[WordPress] 外掛管理選單開發 - 建立後台管理頁面的完整教學
下一篇:[WordPress] Shortcodes 短碼開發教學 - 建立自訂內容功能
