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 時(shí),接收表單提交的 wp-admin/options.php 頁面會(huì)進(jìn)行相當(dāng)嚴(yán)格的權(quán)限檢查。用戶具有 manage_options 能力才能保存數(shù)據(jù)。

為什么使用設(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é)上面。

register_setting() 以及所提及的 add_settings_*() 函數(shù)都應(yīng)該添加到 admin_init。

添加設(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ì)有幫助。

當(dāng)我們單獨(dú)訪問許多選項(xiàng)數(shù)據(jù)時(shí),可能導(dǎo)致許多單獨(dú)的數(shù)據(jù)庫事務(wù),通常,數(shù)據(jù)庫事務(wù)是昂貴的操作(就時(shí)間和服務(wù)器資源而言)而把許多選項(xiàng)作為數(shù)組存儲(chǔ)和獲取時(shí),只會(huì)產(chǎn)生一個(gè)數(shù)據(jù)庫事務(wù),這是一種比較理想的操作。

函數(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í)。

請(qǐng)?jiān)趪L試創(chuàng)建自定義設(shè)置頁面之前閱讀這些章節(jié)。

以下示例可以幫助我們快速了解怎么創(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
}

我們提供 WordPress主題和插件定制開發(fā)服務(wù)

本站長(zhǎng)期承接 WordPress主題、插件、基于 WooCommerce 的商店商城開發(fā)業(yè)務(wù)。 我們有 10 年WordPress開發(fā)經(jīng)驗(yàn),如果你想 用WordPress開發(fā)網(wǎng)站, 請(qǐng)聯(lián)系微信: iwillhappy1314,或郵箱: [email protected] 咨詢。

發(fā)表回復(fù)

您的郵箱地址不會(huì)被公開。 必填項(xiàng)已用 * 標(biāo)注

*