EP126. “WordPress Settings API:注册设置与自动生成表单”
🔒 登录后可标记已读学习 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_options表option_name列的键名;$args里sanitize_callback指定净化函数(这里先用 WordPress 内建的通用函数sanitize_text_field,下一讲会讲怎么换成自己写的、带验证逻辑的净化函数),default是数据库里还没有值时的默认值- 存储设计上的取舍:这个「显示位置」选项本可以存成
"beginning"/"end"这种语义化字符串,作者选择存0/1这种更省空间的编码,具体存什么完全是自己定的规则,只要前后端读写时约定一致即可 add_settings_field($id, $label, $callback, $page, $section):$id要跟register_setting()里的$option_name一致;$label是表单里这一行的文字标签;$callback用array($this, '方法名')指向负责输出这个字段具体 HTML(比如下拉框、输入框)的方法;$page、$section分别对应页面 slug 和分组 ID,把这个字段「安放」到正确的位置add_settings_section($id, $title, $callback, $page):$title(分组标题)和$callback(分组说明文字的输出函数)都可以传null,表示不需要这些可选的展示内容,但参数本身不能省略locationHTML()输出的是纯 HTML(一个<select>下拉框),name属性必须精确匹配注册时用的option_name(wcp_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_init | WP 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