WordPress插件開發(fā)教程手冊(cè) — 設(shè)置選項(xiàng)
本文介紹了WordPress插件開發(fā)中的設(shè)置API和選項(xiàng)API,幫助開發(fā)者構(gòu)建安全、一致的管理界面。設(shè)置API簡(jiǎn)化了表單創(chuàng)建和數(shù)據(jù)管理,而選項(xiàng)API提供了鍵/值存儲(chǔ)系統(tǒng)。文章還提供了快速參考和完整示例,適合希望優(yōu)化插件設(shè)置的開發(fā)者。
為了使管理界面易于構(gòu)建,安全,并在設(shè)計(jì)上和 WordPress 管理界面保持一致,WordPress 提供了兩個(gè)核心 API。
設(shè)置
設(shè)置 API 側(cè)重于為我們提供了一種創(chuàng)建表單和管理表單數(shù)據(jù)的方式。選項(xiàng) API 側(cè)重于為我們提供一種簡(jiǎn)單的鍵/值系統(tǒng)來管理數(shù)據(jù)。
快速參考
請(qǐng)參閱使用設(shè)置 API 和選項(xiàng) API 構(gòu)建自定義設(shè)置頁面的完整示例。
設(shè)置 API
WordPress 2.7 中增加的設(shè)置 API 可以讓我們半自動(dòng)地管理含有設(shè)置表單的后臺(tái)頁面,讓我們自定義設(shè)置頁面,以及這些頁面中的分節(jié)和表單字段。我們可以同時(shí)添加新設(shè)置頁面和與其中的表單字段,也可以添加設(shè)置分節(jié)和表單字段到現(xiàn)有頁面。
開發(fā)者依然需要手動(dòng)注冊(cè)和驗(yàn)證表單字段,但是設(shè)置 API 為我們避免了管理底層選項(xiàng)的大量復(fù)雜調(diào)試。
為什么使用設(shè)置 API
我們可以開發(fā)自己的設(shè)置頁面,而不是使用這個(gè) API,這就出現(xiàn)了一個(gè)問題,設(shè)置 API 可以為我們帶來什么好處,以下是一些好處的簡(jiǎn)要說明。
視覺一致性
使用 API 生成界面元素,可以確保我們的自定義設(shè)置頁面和 WordPress 默認(rèn)管理界面一致,如果我們看到了一個(gè)風(fēng)格是 5 年前的設(shè)置頁面,這個(gè)頁面肯定沒有使用設(shè)置 API,如果使用了設(shè)置 API,自定義頁面的風(fēng)格會(huì)隨著 WordPress 默認(rèn)風(fēng)格一起更新。所以,使用設(shè)置 API 一個(gè)很大好處就是,設(shè)計(jì)頁面看起來就像該有的樣子(和 WordPress 默認(rèn)風(fēng)格一致),感謝 WordPress 的天才設(shè)計(jì)師們,他們的工作看起來很棒。
健壯性(面向未來)
由于設(shè)置API 是 WordPress 核心的一部分,任何更新都將自動(dòng)更新我們的設(shè)置頁面,如果我們創(chuàng)建了自己的設(shè)置頁面,WordPress 的內(nèi)核更新可能會(huì)破壞我們的自定義設(shè)置。會(huì)有越來越多的開發(fā)者測(cè)試和維護(hù)這些設(shè)置 API 代碼,所以他們會(huì)更加穩(wěn)定。
工作更輕松
當(dāng)然,最直接的好處是 WordPress 的設(shè)置 API 在底層默默的為我們做了很多工作,以下是一些例子:
- 處理表單提交 – 讓 WordPress 處理并存儲(chǔ) $_POST 提交
- 包括安全措施 – 可以讓我們獲得額外的安全措施,如隨機(jī)數(shù)驗(yàn)證
- 清理數(shù)據(jù) – 可以和 WordPress 其他部分一樣,自動(dòng)為我們清理數(shù)據(jù),以確保提交的字符串可以安全的使用
函數(shù)參考
| 設(shè)置注冊(cè)/注銷注冊(cè) | 添加字段/分節(jié) |
|---|---|
| register_setting() unregister_setting() | add_settings_section() add_settings_field() |
| 選項(xiàng)表單渲染 | 錯(cuò)誤信息 |
|---|---|
| settings_fields() do_settings_sections() do_settings_fields() | add_settings_error() get_settings_errors() settings_errors() |
使用設(shè)置 API
添加設(shè)置
我們可以使用?register_setting() 來定義一個(gè)新的設(shè)置,此函數(shù)會(huì)在 {$wpdb->prefix}_options 數(shù)據(jù)表中插入一條記錄??梢允褂?add_settings_section()?在現(xiàn)有設(shè)置頁面上添加新分節(jié)??梢允褂?add_settings_field()?將新字段添加到現(xiàn)有的分節(jié)上面。
添加設(shè)置
register_setting(
string $option_group,
string $option_name,
callable $sanitize_callback = ''
);
有關(guān)參數(shù)的完整說明,請(qǐng)參閱關(guān)于 register_setting() 的函數(shù)參考。
添加分節(jié)
add_settings_section(
string $id,
string $title,
callable $callback,
string $page
);
分節(jié)是我們?cè)?WordPress 設(shè)置頁面上看到的帶有共享標(biāo)題的設(shè)置組。在插件中,我們可以向現(xiàn)有的設(shè)置頁面添加新分節(jié),而不是創(chuàng)建一個(gè)新頁面。這可以躺我們的插件更容易維護(hù),并降低用戶的學(xué)習(xí)和使用成本。
有關(guān)參數(shù)的完整說明,請(qǐng)參閱關(guān)于 add_settings_section() 的函數(shù)參考。
示例
<?php
function wporg_settings_init(){
// 為 閱讀 頁面注冊(cè)新設(shè)置
register_setting('reading', 'wporg_setting_name');
// 在閱讀頁面上注冊(cè)新分節(jié)
add_settings_section(
'wporg_settings_section',
'WPOrg Settings Section',
'wporg_settings_section_cb',
'reading'
);
// 閱讀頁面中,在 the wporg_settings_section 分節(jié)上注冊(cè)新設(shè)置
add_settings_field(
'wporg_settings_field',
'WPOrg Setting',
'wporg_settings_field_cb',
'reading',
'wporg_settings_section'
);
}
/**
* 注冊(cè) wporg_settings_init 到 admin_init Action 鉤子
*/
add_action('admin_init', 'wporg_settings_init');
/**
* 回調(diào)函數(shù)
*/
// 分節(jié)內(nèi)容回調(diào)
function wporg_settings_section_cb() {
echo '<p>WPOrg Section Introduction.</p>';
}
// 字段內(nèi)容回調(diào)
function wporg_settings_field_cb() {
// 獲取我們使用 register_setting() 注冊(cè)的字段的值
$setting = get_option('wporg_setting_name');
// 輸出字段
?>
<input type=text name=wporg_setting_name value=<?php echo isset( $setting ) ? esc_attr( $setting ) : ''; ?>>
<?php
}
獲取設(shè)置
get_option(
string $option,
mixed $default = false
);
使用 get_option() 函數(shù)可以獲取設(shè)置數(shù)據(jù),該函數(shù)接受兩個(gè)參數(shù):選項(xiàng)的名稱和該選項(xiàng)的可選默認(rèn)值。
示例
// 獲取我們上面使用 register_setting() 注冊(cè)的選項(xiàng)值
$setting = get_option('wporg_setting_name');
選項(xiàng) API
WordPress 1.0 中引入的選項(xiàng) API 可以讓我們添加、獲取、更新和刪除 WordPress 選項(xiàng),結(jié)合設(shè)置 API,我們可以控制設(shè)置頁面中的自定義選項(xiàng)。
選項(xiàng)在什么地方保存?
選項(xiàng)存儲(chǔ)在 {$wpdb->prefix}_options 數(shù)據(jù)表中。$wpdb->prefix 由 wp-config.php 配置文件中的 $table_prefix 變量定義。
怎么存儲(chǔ)選項(xiàng)?
選項(xiàng)可以以單個(gè)值或者數(shù)組的形式存儲(chǔ)在 WordPress 數(shù)據(jù)庫中。
單個(gè)值
保存為單個(gè)值的時(shí)候,選項(xiàng)值為單個(gè)字符串、整數(shù)等。
<?php
// add a new option
add_option('wporg_custom_option', 'hello world!');
// get an option
$option = get_option('wporg_custom_option');
數(shù)組
保存為數(shù)組時(shí),選項(xiàng)值為一個(gè)數(shù)組。
<?php
// array of options
$data_r = ['title' => 'hello world!', 1, false];
// add a new option
add_option('wporg_custom_option', $data_r);
// get an option
$options_r = get_option('wporg_custom_option');
// output the title
echo esc_html($options_r['title']);
如果我們需要保存大量選項(xiàng),把這些選項(xiàng)保存為數(shù)組,對(duì)性能提升可能會(huì)有幫助。
函數(shù)參考
| 添加選項(xiàng) | 獲取選項(xiàng) | 更新選項(xiàng) | 刪除選項(xiàng) |
|---|---|---|---|
| add_option() | get_option() | update_option() | delete_option() |
| add_site_option() | get_site_option() | update_site_option() | delete_site_option() |
自定義設(shè)置頁面
創(chuàng)建自定義設(shè)置頁面需要用到?創(chuàng)建管理菜單,使用設(shè)置 API?和選項(xiàng) API?中的相關(guān)知識(shí)。
以下示例可以幫助我們快速了解怎么創(chuàng)建自定義設(shè)置頁面。
創(chuàng)建自定義設(shè)置頁面的完整示例
下面是創(chuàng)建自定義設(shè)置頁面的一個(gè)完整示例,以下代碼中,我們添加了一個(gè)名為 WPOrg 的頂級(jí)菜單,注冊(cè)了一個(gè)名為 wporg_options 的選項(xiàng),并使用設(shè)置 API 和選項(xiàng) API 執(zhí)行了一個(gè) CRUD 增查改刪操作(包含顯示錯(cuò)誤/更新消息)
<?php
/**
* @internal never define functions inside callbacks.
* these functions could be run multiple times; this would result in a fatal error.
*/
/**
* custom option and settings
*/
function wporg_settings_init() {
// register a new setting for wporg page
register_setting( 'wporg', 'wporg_options' );
// register a new section in the wporg page
add_settings_section(
'wporg_section_developers',
__( 'The Matrix has you.', 'wporg' ),
'wporg_section_developers_cb',
'wporg'
);
// register a new field in the wporg_section_developers section, inside the wporg page
add_settings_field(
'wporg_field_pill', // as of WP 4.6 this value is used only internally
// use $args' label_for to populate the id inside the callback
__( 'Pill', 'wporg' ),
'wporg_field_pill_cb',
'wporg',
'wporg_section_developers',
[
'label_for' => 'wporg_field_pill',
'class' => 'wporg_row',
'wporg_custom_data' => 'custom',
]
);
}
/**
* register our wporg_settings_init to the admin_init action hook
*/
add_action( 'admin_init', 'wporg_settings_init' );
/**
* custom option and settings:
* callback functions
*/
// developers section cb
// section callbacks can accept an $args parameter, which is an array.
// $args have the following keys defined: title, id, callback.
// the values are defined at the add_settings_section() function.
function wporg_section_developers_cb( $args ) {
?>
<p id=<?php echo esc_attr( $args[ 'id' ] ); ?>><?php esc_html_e( 'Follow the white rabbit.', 'wporg' ); ?></p>
<?php
}
// pill field cb
// field callbacks can accept an $args parameter, which is an array.
// $args is defined at the add_settings_field() function.
// wordpress has magic interaction with the following keys: label_for, class.
// the label_for key value is used for the for attribute of the <label>.
// the class key value is used for the class attribute of the <tr> containing the field.
// you can add custom key value pairs to be used inside your callbacks.
function wporg_field_pill_cb( $args ) {
// get the value of the setting we've registered with register_setting()
$options = get_option( 'wporg_options' );
// output the field
?>
<select id=<?php echo esc_attr( $args[ 'label_for' ] ); ?>
data-custom=<?php echo esc_attr( $args[ 'wporg_custom_data' ] ); ?>
name=wporg_options[<?php echo esc_attr( $args[ 'label_for' ] ); ?>]
>
<option value=red <?php echo isset( $options[ $args[ 'label_for' ] ] ) ? ( selected( $options[ $args[ 'label_for' ] ], 'red', false ) ) : ( '' ); ?>>
<?php esc_html_e( 'red pill', 'wporg' ); ?>
</option>
<option value=blue <?php echo isset( $options[ $args[ 'label_for' ] ] ) ? ( selected( $options[ $args[ 'label_for' ] ], 'blue', false ) ) : ( '' ); ?>>
<?php esc_html_e( 'blue pill', 'wporg' ); ?>
</option>
</select>
<p class=description>
<?php esc_html_e( 'You take the blue pill and the story ends. You wake in your bed and you believe whatever you want to believe.', 'wporg' ); ?>
</p>
<p class=description>
<?php esc_html_e( 'You take the red pill and you stay in Wonderland and I show you how deep the rabbit-hole goes.', 'wporg' ); ?>
</p>
<?php
}
/**
* top level menu
*/
function wporg_options_page() {
// add top level menu page
add_menu_page(
'WPOrg',
'WPOrg Options',
'manage_options',
'wporg',
'wporg_options_page_html'
);
}
/**
* register our wporg_options_page to the admin_menu action hook
*/
add_action( 'admin_menu', 'wporg_options_page' );
/**
* top level menu:
* callback functions
*/
function wporg_options_page_html() {
// check user capabilities
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// add error/update messages
// check if the user have submitted the settings
// wordpress will add the settings-updated $_GET parameter to the url
if ( isset( $_GET[ 'settings-updated' ] ) ) {
// add settings saved message with the class of updated
add_settings_error( 'wporg_messages', 'wporg_message', __( 'Settings Saved', 'wporg' ), 'updated' );
}
// show error/update messages
settings_errors( 'wporg_messages' );
?>
<div class=wrap>
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<form action=options.php method=post>
<?php
// output security fields for the registered setting wporg
settings_fields( 'wporg' );
// output setting sections and their fields
// (sections are registered for wporg, each field is registered to a specific section)
do_settings_sections( 'wporg' );
// output save settings button
submit_button( 'Save Settings' );
?>
</form>
</div>
<?php
}