Submenu pages delete settings from options array when saved

I’m writing a theme and adding a menu with several submenu pages. It works fine, except that I’m trying to use only one array to save all the settings into the database and this is causing some issues.

The problem is that when each submenu pages is saved, it only saves the values from that page to the array and removes all the other values from the other pages that were stored before so the array only ends up holding the values from one page at a time.

Read More

Here are the functions where I create the pages and register the setting.

add_action('admin_menu', 'theme_add_admin');
add_action('admin_init', 'register_theme_settings');

function theme_add_admin() {

add_menu_page( 'Theme Settings', 'Theme Settings', 'update_themes', 'themesettings', 'settings_messages_page');
add_submenu_page( 'themesettings', 'messages', 'Titles and Messages', 'update_themes', 'themesettings');
add_submenu_page( 'themesettings', 'layout', 'Layout', 'update_themes', 'settings_layout', 'settings_layout_page');

add_settings_messages();
add_settings_layout();

}

function register_theme_settings() {
register_setting( THEMENAME . '_settingsgroup', THEMENAME . '_settings', 'validate_options' );
}

In add_settings_messages() and add_settings_layout I add the sections and fields:

function add_settings_layout() {

add_settings_section('layout_styles', 'Archive Layout', 'settings_layout_styles_fn', __FILE__);

add_settings_field('layout_index', 'Home Page Post Style', 'layout_home_fn', __FILE__, 'layout_styles');
add_settings_field('layout_paged', 'Paged Archives Post Style', 'layout_paged_fn', __FILE__, 'layout_styles');

}

And here’s the page display function:

function settings_layout_page() { 
?>
<div class="wrap">
    <div class="icon32" id="icon-options-general"><br></div>
    <h2>Layout</h2>

    <form action="options.php" method="post">
    <?php settings_fields(THEMENAME . '_settingsgroup'); ?>
    <?php do_settings_sections('settings_layout'); ?>
    <p class="submit">
        <input name="Submit" type="submit" class="button-primary" value="<?php esc_attr_e('Save Changes'); ?>" />
    </p>

    </form>


</div>
<?php
}

I’m probably missing something obvious here, any help would be appreciated.

Related posts

Leave a Reply

2 comments

  1. Yep you are missing something, On your validate_options function you need to:

    • get an array of all existing options.
    • update only the options your Submenu
      page handles.
    • return that array.

    So something like:

    function validate_options($input){
        //do regular validation stuff
        //...
        //...
    
        //get all options
        $options = get_option(THEMENAME . '_settings');
        //update only the neede options
        foreach ($input as $key => $value){
            $options[$key] = $value;
        }
        //return all options
        return $options;
    }
    
  2. “Disappearing from options array” sounds like it might be stashed in the “notoptions” array. Check that with something like:

      $notoptions = wp_cache_get( 'notoptions', 'options' );
    

    Worse comes to worse, maybe listen for the add_option hook and see what’s going on.

      do_action( 'add_option', $name, $value );