WordPress函数:settings_errors:在 WordPress 设置页面显示管理通知

编辑文章

简介

settings_errors 函数是 WordPress Settings API 的配套工具,专门用于在后台“设置”选项页面(或使用相同API创建的自定义页面)上,清晰地向管理员反馈设置保存成功、失败或需要修正的错误等系统通知。

语法

该函数定义于 wp-admin/options-head.php 文件,其标准调用依赖于 add_settings_error() 函数预先存储的错误信息。它的工作就是将这些存储的信息渲染成前端的管理员通知(admin notice)。

函数签名:

settings_errors( $setting = '', $sanitize = false, $hide_on_update = false )

参数详解:

参数名 类型 默认值 说明
$setting string '' (空字符串) 要显示通知的“设置字段组”的Slug。通常对应 register_setting() 函数注册的选项组名。留空则显示当前页面所有设置组的通知。
$sanitize boolean false 是否在显示前对通知信息进行二次安全处理true 时会调用 sanitize_text_field() 处理信息字符串,提供额外的输出安全层。
$hide_on_update boolean false 是否在“设置已更新”通用通知出现时隐藏本函数输出。设置为 true 可避免在页面顶部出现重复通知,适用于将通知定位在表单附近显示的场景。

返回值: 无。该函数直接输出(echo)生成的通知HTML代码。

用法

基础用法

最常见的情况是在你使用 Settings API 创建的自定义选项页面回调函数中,在表单之前或之后调用此函数,以显示该页面所有设置操作产生的通知。

// 假设在 `myplugin_admin_page` 回调函数中输出页面内容
function myplugin_admin_page() {
    // 在表单之前显示所有通知(例如错误提示)
    settings_errors();

    // 然后输出你的设置表单
    ?>
    <div class="wrap">
        <h1>我的插件设置</h1>
        <form action="options.php" method="post">
            <?php
            // 输出设置字段、隐藏的nonce字段等
            settings_fields( 'myplugin_options_group' );
            do_settings_sections( 'myplugin_settings_page' );
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

为什么放在这里?settings_errors() 放在表单上方是符合用户习惯的UX设计。用户在提交表单后,视线会自然地从页面顶部开始扫描,首先看到操作结果的反馈(成功或错误),然后再是表单本身,这能有效引导后续操作。

进阶用法

你可以通过组合参数,实现更精细的通知控制。

场景一:仅显示特定设置字段的错误。
当你的设置页面包含多个逻辑上独立的模块时,将错误通知紧挨着相关模块显示,可以提供更精准的上下文。

function myplugin_complex_admin_page() {
    ?>
    <div class="wrap">
        <h1>复杂设置</h1>

        <h2>基本设置</h2>
        <form action="options.php" method="post">
            <?php settings_fields( 'myplugin_basic_group' ); ?>
            <!-- ... 基本设置字段 ... -->
            <?php submit_button( '保存基本设置' ); ?>
        </form>
        <?php
        // 只显示与 `myplugin_basic_group` 相关的通知
        settings_errors( 'myplugin_basic_group' );
        ?>

        <hr>

        <h2>高级设置</h2>
        <form action="options.php" method="post">
            <?php settings_fields( 'myplugin_advanced_group' ); ?>
            <!-- ... 高级设置字段 ... -->
            <?php submit_button( '保存高级设置' ); ?>
        </form>
        <?php
        // 只显示与 `myplugin_advanced_group` 相关的通知
        settings_errors( 'myplugin_advanced_group' );
        ?>
    </div>
    <?php
}

场景二:在页面顶部显示通用成功通知,在表单旁显示详细错误。
利用 $hide_on_update 参数避免通知重复。

function myplugin_ux_optimized_page() {
    // 在顶部显示所有通知,但如果只是一个普通的“设置已保存”成功通知,则隐藏。
    // 这通常用于显示那些需要引起全局注意的严重错误。
    settings_errors( '', false, false );

    ?>
    <div class="wrap">
        <h1>优化体验的设置页面</h1>
        <form action="options.php" method="post">
            <?php
            settings_fields( 'myplugin_options' );
            do_settings_sections( 'myplugin_page' );
            submit_button();
            ?>
        </form>
        <?php
        // 在表单下方再次显示通知,此次即使有“设置已保存”通知也强制显示。
        // 这确保了用户在处理完表单后,能立刻在视线范围内(表单附近)看到操作结果。
        // `$hide_on_update` 设为 false 是关键。
        settings_errors( '', false, false );
        ?>
    </div>
    <?php
}

易错点

admin_notices 钩子中错误调用

错误示例:

add_action( 'admin_notices', function() {
    settings_errors();
} );

后果与原因: 这会导致同一个通知在后台几乎所有管理页面的顶部出现多次,严重干扰用户。因为 admin_notices 钩子在每个后台页面都会执行,而 settings_errors() 被设计为仅在处理 options.php 或特定设置页面的上下文中才有输出。正确的做法是直接将 settings_errors() 调用写在你的设置页面回调函数体内,如上文基础用法所示。

忘记调用 add_settings_error() 就期待通知出现

settings_errors() 本身不产生通知,它只负责“显示”。通知信息需要通过 add_settings_error( $setting, $code, $message, $type ) 函数在设置字段的验证回调函数处理逻辑中预先添加。如果保存设置后没有通知,首先应检查 add_settings_error() 是否被正确执行。

对用户输入的通知信息不进行转义

危险示例:add_settings_error() 中直接使用未经处理的用户输入。

// 在验证函数中
add_settings_error(
    'my_setting',
    'error_code',
    $_POST['custom_message'], // 高危!用户可注入任意HTML/JS
    'error'
);

后果与原因: 这会导致存储型XSS漏洞。攻击者可以提交包含恶意脚本的“消息”,当管理员查看设置页面时,脚本会以其高权限执行。解决方案是始终对要显示给用户的信息进行消毒或转义。可以利用 settings_errors()$sanitize = true 参数提供最后一道防线,但更佳实践是在源头处理:

$safe_message = sanitize_text_field( $_POST['custom_message'] ); // 或 wp_kses_post 等
add_settings_error( 'my_setting', 'error_code', $safe_message, 'error' );

最佳实践

与 Settings API 的规范集成

settings_errors() 的威力在于与 Settings API 的无缝协作。最佳实践是遵循以下标准流程:
1. 注册设置 (register_setting):定义选项组。
2. 添加字段 (add_settings_field):定义具体的输入项。
3. 定义验证 (sanitize_callback):在验证回调函数中,使用 add_settings_error() 针对无效输入添加错误通知。在这里添加错误是通知能够显示的根本
4. 页面渲染:在页面回调函数中,于表单的合适位置调用 settings_errors() 来集中显示上述步骤累积的所有通知。

这种模式确保了业务逻辑(验证和添加错误)与显示逻辑(渲染通知)的清晰分离,符合 WordPress 核心设计模式,使代码更易于维护和调试。

通知信息的可读性与用户体验

一条好的通知信息应该直接指导用户下一步该做什么。
* 避免模糊:不要说“保存出错”,而应该说““API密钥”不能为空,请填写后重新保存。”
* 善用消息类型add_settings_error()$type 参数(‘error’, ‘warning’, ‘success’, ‘info’)对应不同的 CSS 类(如 .notice-error),会产生不同颜色的侧边条。正确使用类型可以快速传递信息状态。
* 保持简洁:通知是摘要,详细说明应放在字段旁的描述文字中。

确保通知仅出现在预期位置

为了避免通知“泄漏”到其他页面,除了避免在全局钩子中调用外,还可以在调用前增加条件判断。

function myplugin_render_settings_page() {
    // 检查当前屏幕是否是我们的设置页面
    $current_screen = get_current_screen();
    if ( $current_screen->id !== 'toplevel_page_myplugin_slug' ) {
        return;
    }
    settings_errors();
    // ... 其余页面代码 ...
}

这是一种防御性编程,确保了即使在复杂的插件环境中,通知也只在它该出现的地方渲染,提升了代码的健壮性。