I'm following @Otto's tutorial on Settings API. I managed to save the plugin settings into the options table, but by any means can't save any fields.

*   Add Settings SubMenu
*   Thanks to: Otto
*   Following: http://ottopress.com/2009/wordpress-settings-api-tutorial/
function plugins_settings_page() {
        'my-page-slug',       //$parent_slug
        'Plugin Settings',                 //$page_title
        'Plugin Settings',                 //$menu_title
        'manage_options',                   //$capability
        'plugin-settings',                 //$menu_slug
        'plugins_settings_page_callback'    // callback function

add_action('admin_menu', 'plugins_settings_page');

function plugins_settings_page_callback() {
    <div class="wrap">
        <h2>Plugin Settings</h2>
        <?php settings_errors(); ?>
        <form action="options.php" method="post">
            <?php settings_fields('plugin_options'); ?>
            <?php do_settings_sections('plugin_settings'); ?>
            <p class="submit">
                <?php submit_button(); ?>
    </div> <!-- .wrap -->

function plugin_options_init(){

    if( false == get_option( 'plugin_settings' ) ) {
        add_option( 'plugin_settings' );

        'plugin_options',          // Option group*
        'plugin_options',          // Option Name*
        'plugin_options_validate'   // Sanitize Callback Function
        'plugin_general',              // ID/Slug*
        'General Settings',            // Name*
        'plugin_section_callback',      // Callback*
        'plugin_settings'                    // Page on which to add this section of options*
        'plugin_function_activation',       // ID*
        'Activate Plugin Function',        // Title*
        'plugin_setting_field',    // Callback Function*
        'plugin_settings',                   // Page (Plugin)*
        'plugin_general'               // Section

// add the admin settings and such
add_action( 'admin_init', 'plugin_options_init' );

function plugin_section_callback() {
    //echo '<p>Main description of this section here.</p>';

function plugin_setting_field() {
    $options = get_option('plugin_options');
    echo "<input name='plugin_options[plugin_settings_field]' id='plugin_function_activation' type='checkbox' value='1' ".checked( 1, $options['plugin_settings_field'], false ) . " />";

/*// validate our options
function plugin_options_validate($input) {
    $options = get_option('plugin_options');
    $options['text_string'] = trim($input['text_string']);
    if(!preg_match('/^[a-z0-9]{32}$/i', $options['text_string'])) {
        $options['text_string'] = '';
    return $options;

Issues I assumed and checked are:

  1. I'm using add_submenu_page() where Otto used add_options_page()
  2. I added the following portion extra:

    if( false == get_option( 'plugin_settings' ) ) {
        add_option( 'plugin_settings' );
  3. Where I used underscore-separated value: do_settings_sections('plugin_settings'), Otto used single value do_settings_sections('plugin')

  4. I'm using a checkbox, where Otto used a textbox

My approaches the above mentioned situations:

  1. Found no real difference except the parent slug, so it's not causing the problem
  2. Without that block I couldn't save anything into the db, so I added this
  3. It's not causing problem as I can put data into db even with my value
  4. For the name="" parameter both are the same, so saving won't be affected

And here's the current state of db, option_value is empty: options table for plugin settings

What's causing me the pain?

  • You should activate the WP_DEBUG constant in wp_config.php There are a lot of typos such as unwanted "s" and undefined indexes. – JMau Sep 18 '14 at 19:22
  • @JMau both the WP_DEBUG and SCRIPT_DEBUG is true in my case, but no such warning is displayed. Could you please point the unwanted s and where are those undefined indexes? I actually couldn't see 'em. :( – Mayeenul Islam Sep 19 '14 at 2:31
  • Really? Ok. In your code you got "plugin_setting_field" and "plugin_settings_field", doesn't feel right. – JMau Sep 19 '14 at 17:52
  • @JMau plugin_setting_field is nothing but a callback function, it can be anything, even xyz()... and plugin_settings_field is the option name with which I'm storing data into Options. So all of them are good - aren't they? – Mayeenul Islam Sep 21 '14 at 3:55
  • Oh yes, read that too fast sorry. – JMau Sep 28 '14 at 20:37

You appear to have the validation function commented out. Try this one for testing only:

function plugin_options_validate($input) {
   return $input;

Now do your options save?

Validation functions are not optional. They take the settings, validate them, and return the valid ones. If you don't have a validation function then the settings won't be returned from it, and therefore won't be saved.

The function I just gave is horrifically unsafe, because it does no validation. You need to have code here to check the incoming settings, make sure they are valid, and to then return the valid ones. Without this, settings cannot be saved.

  • Thanks a lot for the tips, and it's saving data. BTW I commented the function out because I followed the Codex, it's saying the $sanitize_callback function is optional, so I thought, even if I omit the line from the register_setting() function, it should work. But what you said, it's mandatory, so should I edit the Codex page? – Mayeenul Islam Sep 19 '14 at 2:37
  • 1
    Technically, yes, if you leave out that third parameter to the register_setting call, then no validation callback is necessary. You should never do that, validation is an important security step. – Otto Sep 19 '14 at 16:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.