WordPress函数:add_settings_section 创建设置区域
编辑文章简介
在WordPress后台设置页面中创建逻辑分组区域,将相关的设置字段组织在一起,提升用户体验和管理界面清晰度。
语法
add_settings_section( string $id, string $title, callable $callback, string $page )
函数定义位于 wp-admin/includes/template.php,主要通过 do_settings_sections() 函数在页面渲染时调用显示。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
$id |
string | 是 | – | 区域唯一标识符(slug格式),用于内部引用 |
$title |
string | 是 | – | 显示在区域顶部的标题文字 |
$callback |
callable | 是 | – | 输出区域描述或其他HTML内容的回调函数 |
$page |
string | 是 | – | 区域所属的设置页面slug(需与add_settings_field的page参数一致) |
返回值:无返回值,函数直接注册区域到全局 $wp_settings_sections 数组中。
用法
基础用法
以下完整示例展示如何创建自定义设置页面并添加一个设置区域:
// 在主题的functions.php或插件文件中添加
add_action('admin_menu', 'myplugin_register_settings_page');
function myplugin_register_settings_page() {
// 首先添加设置页面,区域将显示在此页面内
add_options_page(
'我的插件设置', // 页面标题
'我的插件', // 菜单标题
'manage_options', // 权限要求
'myplugin-settings', // 页面slug(与add_settings_section的$page对应)
'myplugin_settings_html' // 回调函数,输出页面HTML
);
}
add_action('admin_init', 'myplugin_register_settings');
function myplugin_register_settings() {
// 注册一个设置区域
add_settings_section(
'myplugin_basic_section', // 区域ID
'基础设置', // 区域标题
'myplugin_section_description', // 显示描述的回调函数
'myplugin-settings' // 所属页面slug,必须与add_options_page一致
);
// 通常在此函数内继续注册设置字段(add_settings_field)
}
// 区域描述回调函数
function myplugin_section_description() {
echo '<p>这里是基础设置区域的说明文字,用于指导用户填写下面的字段。</p>';
}
// 设置页面HTML结构回调(由add_options_page指定)
function myplugin_settings_html() {
// 检查用户权限
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form action="options.php" method="post">
<?php
// 输出设置区域和字段
settings_fields('myplugin_options'); // 选项组名称
do_settings_sections('myplugin-settings'); // 页面slug
submit_button();
?>
</form>
</div>
<?php
}
进阶用法
使用闭包作为回调函数
当描述逻辑简单且无需复用时,可以使用闭包减少函数定义:
add_action('admin_init', function() {
add_settings_section(
'myplugin_advanced_section',
'高级配置',
function() {
// 闭包内部可以访问外部变量,但要注意作用域
$help_link = 'https://example.com/docs';
printf(
'<p>如需更多帮助,请查看<a href="%s" target="_blank">官方文档</a>。</p>',
esc_url($help_link)
);
},
'myplugin-settings'
);
});
动态生成区域标题
根据条件动态生成区域内容,例如多站点环境下的差异显示:
add_action('admin_init', 'myplugin_conditional_section');
function myplugin_conditional_section() {
$section_title = '常规设置';
if (is_multisite()) {
$section_title = '网络设置(多站点)';
}
add_settings_section(
'myplugin_network_section',
$section_title, // 动态标题
function() {
if (is_multisite()) {
echo '<p>这些设置将应用于网络中的所有站点。</p>';
} else {
echo '<p>这些设置仅影响当前站点。</p>';
}
},
'myplugin-settings'
);
}
易错点
区域ID冲突
使用通用ID(如general、advanced)可能导致与其他插件冲突。WordPress不会阻止重复ID注册,但后注册的会覆盖先注册的,导致区域丢失。
// 错误:ID太通用,易冲突
add_settings_section('general', '常规', 'callback', 'page');
// 正确:添加唯一前缀
add_settings_section('myplugin_general', '常规', 'callback', 'page');
忘记输出区域描述
注册了回调函数但没有在其中输出任何内容,用户会看到空区域而困惑。即使不需要描述,也应输出简单说明或至少保持回调函数存在。
// 错误:回调函数为空
function myplugin_empty_callback() {
// 什么都没有
}
// 正确:至少输出一个简单的段落
function myplugin_proper_callback() {
echo '<p>请配置以下选项:</p>';
}
页面slug不匹配
add_settings_section的$page参数必须与add_options_page(或其他添加页面的函数)使用的slug完全一致,包括大小写。
// 添加页面时使用这个slug
add_options_page('标题', '菜单', '权限', 'my-plugin-page', 'callback');
// 错误:slug不一致(多了一个连字符)
add_settings_section('section_id', '标题', 'callback', 'my--plugin-page');
// 错误:大小写不一致
add_settings_section('section_id', '标题', 'callback', 'My-Plugin-Page');
// 正确:完全匹配
add_settings_section('section_id', '标题', 'callback', 'my-plugin-page');
在错误的钩子中注册
add_settings_section必须在admin_init钩子或更早的钩子中调用,如果在admin_menu之后调用可能无法正确显示。
// 错误:在admin_menu的回调函数中直接调用(可能太晚)
add_action('admin_menu', function() {
add_options_page(...);
add_settings_section(...); // 可能不会显示
});
// 正确:使用admin_init钩子
add_action('admin_menu', 'add_my_page');
add_action('admin_init', 'add_my_sections'); // 分开注册
最佳实践
使用唯一前缀避免冲突
为所有ID、选项名、页面slug添加唯一前缀,通常使用插件/主题的缩写或全名,用下划线连接。
// 使用插件唯一标识作为前缀
define('MYPLUGIN_PREFIX', 'myplugin_');
add_settings_section(
MYPLUGIN_PREFIX . 'general_section', // myplugin_general_section
'常规设置',
'myplugin_general_callback',
MYPLUGIN_PREFIX . 'settings_page' // myplugin_settings_page
);
编写清晰的区域描述回调
描述应简洁明了,指导用户操作,可包含HTML格式但避免复杂样式。对于需要转义的内容,使用相应的转义函数。
function myplugin_section_callback() {
?>
<div class="notice notice-info inline">
<p><strong>重要:</strong>这些设置影响网站前台显示。</p>
<p>如需帮助,请参考我们的
<a href="<?php echo esc_url('https://example.com/help'); ?>" target="_blank">
帮助文档
</a>
</p>
</div>
<?php
}
遵循标准的代码组织模式
将相关设置组织在一起,提高代码可读性和维护性:
class MyPlugin_Settings {
const PAGE_SLUG = 'myplugin_settings';
public function init() {
add_action('admin_init', [$this, 'register_sections']);
add_action('admin_menu', [$this, 'add_menu_page']);
}
public function add_menu_page() {
add_options_page(...);
}
public function register_sections() {
// 基础设置区域
add_settings_section(
'basic',
'基础配置',
[$this, 'render_basic_section'],
self::PAGE_SLUG
);
// 高级设置区域
add_settings_section(
'advanced',
'高级功能',
[$this, 'render_advanced_section'],
self::PAGE_SLUG
);
}
public function render_basic_section() {
echo '<p>配置插件的基本功能。</p>';
}
public function render_advanced_section() {
echo '<p>这些设置仅供高级用户使用。</p>';
}
}
// 初始化
$settings = new MyPlugin_Settings();
$settings->init();
考虑可访问性(Accessibility)
为区域添加适当的ARIA属性,帮助屏幕阅读器用户理解页面结构:
function myplugin_accessible_section_callback() {
?>
<div id="myplugin-settings-description" class="screen-reader-text">
此区域包含所有基础设置选项,请按Tab键在不同字段间切换。
</div>
<p aria-describedby="myplugin-settings-description">
配置以下选项以定制插件行为:
</p>
<?php
}
与设置字段保持逻辑关联
确保区域内的字段在逻辑上属于同一组,避免将不相关的设置放在同一区域。如果设置较多,考虑使用多个标签页而非单个页面内的多个区域。
// 良好的逻辑分组
add_settings_section(
'myplugin_display_section',
'显示设置',
'callback_display', // 包含字体、颜色、布局相关说明
'page'
);
// 在此区域只添加显示相关的字段
add_settings_section(
'myplugin_function_section',
'功能设置',
'callback_function', // 包含功能开关、行为相关说明
'page'
);
// 在此区域只添加功能相关的字段