WP DEVELOP

EP126. “WordPress Settings API:注册设置与自动生成表单”

首页 WordPress 开发课程 插件开发 CH1:PHP 基础 · EP126
约 15 分钟· #EP126#插件开发 CH1:PHP 基础
🔒 登录后可标记已读

学习 WordPress 的 Settings API——一套让你不用手写表单验证、nonce 安全校验、存取数据库逻辑,就能做出标准后台设置页面的机制。核心分三步:register_setting() 告诉 WordPress 这个设置叫什么名字、怎么净化、默认值是什么;add_settings_section() 建一个分组区块;add_settings_field() 把一个具体的字段和它对应的 HTML 输出函数挂到某个分组下。最后在页面 HTML 里只需要调用 settings_fields() + do_settings_sections() + submit_button() 三个函数,WordPress 就会自动把注册好的字段拼成标准表单、处理提交、存进数据库的 wp_options 表。


涉及文件

  • wp-content/plugins/our-first-unique-plugin/our-first-unique-plugin.php (修改)

代码实现

完整文件(新增 settings()locationHTML() 方法,改写 ourHTML()

<?php

/*
  Plugin Name: Our Test Plugin
  Description: A truly amazing plugin.
  Version: 1.0
  Author: Brad
  Author URI: https://www.udemy.com/user/bradschiff/
*/

class WordCountAndTimePlugin {
  function __construct() {
    add_action('admin_menu', array($this, 'adminPage'));
    add_action('admin_init', array($this, 'settings')); // 新增
  }

  // 新增
  function settings() {
    add_settings_section('wcp_first_section', null, null, 'word-count-settings-page');
    add_settings_field('wcp_location', 'Display Location', array($this, 'locationHTML'), 'word-count-settings-page', 'wcp_first_section');
    register_setting('wordcountplugin', 'wcp_location', array('sanitize_callback' => 'sanitize_text_field', 'default' => '0'));
  }

  // 新增
  function locationHTML() { ?>
    <select name="wcp_location">
      <option value="0">Beginning of post</option>
      <option value="1">End of post</option>
    </select>
  <?php }

  function adminPage() {
    add_options_page('Word Count Settings', 'Word Count', 'manage_options', 'word-count-settings-page', array($this, 'ourHTML'));
  }

  function ourHTML() { ?>
    <div class="wrap">
      <h1>Word Count Settings</h1>
      <form action="options.php" method="POST">
      <?php
        settings_fields('wordcountplugin'); // 新增:处理 nonce/安全校验的隐藏字段
        do_settings_sections('word-count-settings-page'); // 新增:自动渲染已注册的字段
        submit_button(); // 新增:标准蓝色 Save Changes 按钮
      ?>
      </form>
    </div>
  <?php }
}

$wordCountAndTimePlugin = new WordCountAndTimePlugin();

关键改动点:

  • register_setting($option_group, $option_name, $args)$option_group 是这批设置的分组名(后面 settings_fields() 要用同一个名字才能对上);$option_name 是真正存进数据库 wp_optionsoption_name 列的键名;$argssanitize_callback 指定净化函数(这里先用 WordPress 内建的通用函数 sanitize_text_field,下一讲会讲怎么换成自己写的、带验证逻辑的净化函数),default 是数据库里还没有值时的默认值
  • 存储设计上的取舍:这个「显示位置」选项本可以存成 "beginning"/"end" 这种语义化字符串,作者选择存 0/1 这种更省空间的编码,具体存什么完全是自己定的规则,只要前后端读写时约定一致即可
  • add_settings_field($id, $label, $callback, $page, $section)$id 要跟 register_setting() 里的 $option_name 一致;$label 是表单里这一行的文字标签;$callbackarray($this, '方法名') 指向负责输出这个字段具体 HTML(比如下拉框、输入框)的方法;$page$section 分别对应页面 slug 和分组 ID,把这个字段「安放」到正确的位置
  • add_settings_section($id, $title, $callback, $page)$title(分组标题)和 $callback(分组说明文字的输出函数)都可以传 null,表示不需要这些可选的展示内容,但参数本身不能省略
  • locationHTML() 输出的是纯 HTML(一个 <select> 下拉框),name 属性必须精确匹配注册时用的 option_namewcp_location),WordPress 才知道提交上来的这个值该存到哪个设置项里
  • 页面模板里三个函数各司其职:settings_fields($option_group) 自动输出 nonce、action 等安全相关的隐藏字段(这一步缺了会导致提交报错,因为 WordPress 的核心处理逻辑 options.php 靠这些隐藏字段判断请求是否合法);do_settings_sections($page_slug) 自动按分组循环输出所有已注册的字段 HTML;submit_button() 输出跟其他 WordPress 后台页面视觉统一的蓝色提交按钮
  • 表单本身 action="options.php" method="POST"——提交后交给 WordPress 核心的 options.php 统一处理保存逻辑,不需要自己写处理提交的代码

[截图:wp-admin Word Count 设置页面,显示 Display Location 下拉框与蓝色 Save Changes 按钮]


Hook / Function 速查

名称类型用途
admin_initWP hook后台初始化时触发,是注册 Settings API 相关内容的标准挂载点
register_setting($group, $name, $args)WP 内建 function告诉 WordPress 这个设置项的分组、名称、净化方式、默认值
add_settings_section($id, $title, $callback, $page)WP 内建 function在设置页面里新建一个字段分组区块
add_settings_field($id, $label, $callback, $page, $section)WP 内建 function把一个具体字段挂到某个分组下,指定它的展示标签和 HTML 输出函数
settings_fields($group)WP 内建 function输出该分组对应的安全隐藏字段(nonce 等)
do_settings_sections($page)WP 内建 function自动渲染指定页面下所有已注册的分组和字段
submit_button()WP 内建 function输出标准样式的提交按钮
sanitize_text_field()WP 内建 function通用文本净化函数,去除多余空白、危险标签等

常见坑

  • 表单里忘记调用 settings_fields()——提交时会报安全校验相关的错误,因为缺少 WordPress 核心要求的 nonce 隐藏字段
  • add_settings_field()/register_setting() 里的名字对不上——add_settings_field() 的第一个参数、HTML 里 <select name="..."> 的属性值、register_setting() 的第二个参数,三处必须完全一致的字符串,任何一处拼错都会导致值存不进去或读不出来
  • 下拉框选完保存后,页面刷新看不到刚保存的值——这是因为 locationHTML() 目前只是静态输出两个选项,没有读取数据库里已保存的值来决定哪个 <option> 该带上 selected,这个问题会在下一讲解决

延伸 / 后续讲座会用到

下一讲会让下拉框正确回显数据库里保存的当前值,并继续用同样的模式注册剩下几个设置项(字符统计、阅读时间等开关)。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 23, EP126