Theme settings default, strange behavior before first save

Don’t rely on the options ever getting saved. Better is for the Theme to function normally, whether or not the user ever visits the Theme Settings page.

First step is to define a function to return your option defaults, either:

  1. Define them in the function, and then reference that function in your option parameters array

    function mytheme_option_parameters() {
        $parameters = array(
            'foo' => array( 
                'name' => 'foo',
                'title' => 'Foo',
                'std' => 'bar'
            ),
            'foo1' => array( 
                'name' => 'foo1',
                'title' => 'Foo1',
                'std' => 'bar1'
            ),
         );
         return $parameters;
    )
    
    function mytheme_option_defaults() {
        $parameters = mytheme_option_parameters;
        $defaults = array();
        foreach ( $parameters as $param ) {
            $defaults[$param['name']] = $param['std'];
        }
        return $defaults;
    } 
    
  2. Define them in your option parameters array, and then loop through that array inside your function.

    function mytheme_option_defaults() {
        $parameters = mytheme_option_parameters;
        $defaults = array();
        foreach ( $parameters as $param ) {
            $defaults[$param['name']] = $param['std'];
        }
        return $defaults;
    } 
    
    function mytheme_option_defaults() {
        $defaults = array(
            'foo' => 'bar',
            'foo1' => 'bar1'
        );
        return $defaults;
    } 
    
    function mytheme_option_parameters() {
        $defaults = mytheme_option_defaults();
        $parameters = array(
            'foo' => array( 
                'name' => 'foo',
                'title' => 'Foo',
                'std' => $defaults['foo'];
            ),
            'foo1' => array( 
                'name' => 'foo1',
                'title' => 'Foo1',
                'std' => $defaults['foo1']
            ),
         );
         return $parameters;
    )
    

Then, when you need to reference your Theme options, do this:

function mytheme_get_options() {
    $defaults = mytheme_option_defaults();
    $options = wp_parse_args( get_option( 'theme_themename_options', array() ), $defaults );
    return $options;
}   

The magic here is the wp_parse_args() call. Basically, if no Theme options are set, then the defaults are used, but if the options are set, then they are used. Any options not set by the user (e.g. a newly added option) will fallback to use the Theme-defined default.

The Theme works out-of-the-box, using Theme-defined defaults, even if the user never visits the Theme Settings page. And if the user never actually saves any settings, the Theme never even writes a DB entry for its options.