How should one implement add_settings_error on custom menu pages?

The Professional WordPress Plugin Development book explains in detail how to properly use the Settings API, and it also demonstrates how to add Menus and Submenus, but unfortunately it doesn’t provide any joined-up examples of this. Whilst I’ve managed to get most of it working, I can’t figure out how to properly implement add_settings_error on custom Menu pages. Here is my code:

function settings_main_validate( $input ) {
$valid['text_string'] = preg_replace( '/[^a-zA-Z]/', '', $input['text_string'] );

if ( $valid['text_string'] != $input['text_string'] ) {
    //add_setting_error: $title, $id, $error_message, $class
    add_settings_error( 'fields_main_input', 'texterror', 'Incorrect value entered!', 'error' );
}   

return $valid;
}                  

The validation above will work great on setting rendered using add_options_page, but will not display the settings errors on pages rendered with add_menu_page.

Related posts

Leave a Reply

3 comments

  1. There are several components to error/notice creation and display process:

    1. add_settings_error() call to add item to stack (global $wp_settings_errors variable).
    2. settings_errors transient that keeps the errors so they survive move from page to page.
    3. settings_errors() function get_settings_errors() to retrieve errors from memory or transient and then displays them.

    These work like a charm for Settings API, but unfortunately they aren’t setup for generic use. On other hand it is trivial to work around that.

    Hook settings_errors() to admin_notices on your plugin’s page, pass the error code to it so it only shows your stuff.

    Manually save errors to settings_errors transient (just stuff that global variable into it).

    Since get_settings_errors() expects hint in GET parameters ($_GET['settings-updated']) that it should check transient instead of memory you can either provide that or get errors from transient yourself and save them back to global variable before your settings_errors() call.

    Update

    You are turning this into bit of a mess with multiple question, so I will try to address your concerns here.

    Settings API does work with admin pages, that don’t use Settings section as base. Your real issue is that in that case error/notice reporting does not work.

    First here is what happens when you post form, set up with Settings API:

    1. Data gets posted to special options.php page.
    2. There data gets sanitized/validated using callback.
    3. Any error/notices that came up during sanitization/validation are collected and saved in transient.
    4. You are redirected back to wherever you came from.

    Now when you load admin page it checks if this page belongs to Settings section and if that case includes tiny options-head.php file, that deals with retrieving and displaying errors notices.

    So the only thing “not working” on other pages is this latter step, which is trivial to do yourself with overview of related function above (I probably went into too much details on transient, you won’t need that for basic case).

  2. A bit late, but I have just been through this. Based on the OP’s code, the best solution I found is to insert this code:

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

    This will add the admin notice display to admin pages rendered using add_menu_page

  3. Simply adding

    include_once 'options-head.php'; 
    

    to my custom menu page’s $function seemed to work fine for displaying the error messages on custom menu pages.