I created theme options page using Settings API, everything works fine but I can’t save options. I tried to figure it out where I missed something but I failed. Any idea what can cause this problem?
Here’s code of my options page
<?php
/**
* This functions registers default options values for Evolutionary theme
* settings
*/
function ev_theme_settings_defaults() {
$options = array(
'color_scheme' => 'blue',
'copyright' => '',
'nav_hide_home' => false,
'nav_hide_sec' => false,
'nav_show_lvl' => false,
'featured_show' => false,
'featured_pause' => false,
'featured_speed' => 5,
'ad1_link' => '',
'ad1_image' => '',
'ad2_link' => '',
'ad2_image' => '',
'ad3_link' => '',
'ad3_image' => '',
'ad4_link' => '',
'ad4_image' => ''
);
return $options;
// Change to apply_filters( 'ev_theme_settings_defaults', $options );
}
/**
* Create helper function for theme colors
*/
function ev_get_valid_color_schemes(){
$color_schemes = array(
'blue' => __( 'Blue', 'evolutionary' ),
'green' => __( 'Green', 'evolutionary' ),
'red' => __( 'Red', 'evolutionary' ),
'black' => __( 'Black', 'evolutionary')
);
return $color_schemes;
}
/**
* Setup initial theme options
*/
function ev_options_init() {
// Set options equal to defaults
global $ev_options;
$ev_options = ev_theme_settings_defaults();
if ( false === $ev_options ) {
$ev_options = ev_theme_settings_defaults();
}
update_option( 'theme_evolutionary_options', $ev_options );
}
add_action( 'after_setup_theme', 'ev_options_init', 9 );
/**
* Add theme options page to admin menu
*/
function ev_menu_options() {
add_theme_page( __( 'Theme Options', 'evolutionary' ), __( 'Theme Options', 'evolutionary' ), 'edit_theme_options', 'evolutionary-settings', 'ev_admin_options_page' );
}
add_action( 'admin_menu', 'ev_menu_options' );
/**
* Register theme options
*/
function ev_register_options() {
register_setting( 'theme_evolutionary_options', 'theme_evolutionary_options', 'ev_options_validate' );
/**
* Defining settings sections and fields
* fist setting creates sections for general options
*/
add_settings_section( 'ev_settings_general_options', __( 'General Options', 'evolutionary' ), 'ev_settings_general_options', 'evolutionary' );
// Creates section for navigation options
add_settings_section( 'ev_settings_nav_options', __( 'Navigation', 'evolutionary' ), 'ev_settings_nav_options', 'evolutionary' );
// Section for featured post options
add_settings_section( 'ev_settings_featured_options', __( 'Featured Posts', 'evolutionary' ), 'ev_settings_featured_options', 'evolutionary' );
// Section for Advertising options
add_settings_section( 'ev_settings_ad_options', __( 'Advertising', 'evolutionary' ), 'ev_settings_ad_options', 'evolutionary' );
/**
* Created empty callbacks for setions
*/
function ev_settings_general_options() {
// Put callback code here
}
function ev_settings_nav_options() {
// callback
}
function ev_settings_featured_options() {
// callback
}
function ev_settings_ad_options() {
// callback
}
/**
* Registered fields
*/
add_settings_field( 'ev_settings_copyright_field', __( 'Copyright Name', 'evolutionary' ), 'ev_settings_copyright_field', 'evolutionary', 'ev_settings_general_options' );
add_settings_field( 'ev_settings_colors_field', __( 'Theme Color', 'evolutionary' ), 'ev_settings_colors_field', 'evolutionary', 'ev_settings_general_options' );
/**
* Fields Callbacks
*/
function ev_settings_copyright_field() {
$ev_options = get_option( 'theme_evolutionary_options' );
//var_dump( $ev_options );
?>
<input name="theme_evolutionary_options[copyright]" type="text" class="regular-text" value="<?php esc_attr_e( $ev_options['copyright'] ); ?>" />
<?php }
// Callback for colorscheme
function ev_settings_colors_field() {
$ev_options = get_option( 'theme_evolutionary_options' );
$color_schemes = ev_get_valid_color_schemes();
echo '<select name="theme_evolutionary_options[color_scheme]">';
foreach( $color_schemes as $value => $caption ) :
?>
<option value="<?php echo $value; ?>" <?php selected( $value, $ev_options['color_scheme'] ); ?>><?php echo $caption; ?></option>
<?php
endforeach;
echo '</select>';
}
} // ev_register_options
add_action( 'admin_init', 'ev_register_options' );
/**
* Creating options page HTML output
*/
function ev_admin_options_page() { ?>
<div class="wrap">
<?php if ( isset( $_GET['settings-updated'] ) ) {
echo "<div class='updated'><p>Theme settings updated successfully.</p></div>";
} ?>
<?php screen_icon(); ?>
<h2><?php _e( 'Theme Options', 'evolutionary' ); ?></h2>
<form action="options.php" method="post">
<?php
settings_fields( 'theme_evolutionary_options' );
do_settings_sections( 'evolutionary' );
?>
<input name="submit" type="submit" class="button-primary" value="<?php _e( 'Save Settings', 'evolutionary' ) ?>" />
<input name="reset" type="submit" class="button-secondary" value="<?php _e( 'Reset Settings', 'evolutionary' ) ?>" />
</form>
</div>
<?php }
function ev_options_validate( $input ) {
$ev_options = get_option( 'theme_evolutionary_options' );
$valid_input = $ev_options;
$ev_options['color_scheme'] = array_key_exists( $ev_options['color_scheme'], ev_get_valid_color_schemes() ) ? $ev_options['color_scheme'] : 'blue';
$ev_options['copytright'] = wp_kses_data( $ev_options['copyright'] );
return $valid_input;
}
@Mamaduka:
Here is why your settings aren’t updating. Your validation function is wrong. To wit:
You’re updating $ev_options, but returning $valid_input. You need to be updating $valid_input, not $ev_options.
Try this instead:
See if that fixes your problem?
EDITED TO ADD:
Your next problem in the validation function is that you’re comparing $ev_options to/against itself, when you need to be evaluating $input against $valid_input.
Instead of this:
Try this:
Specifically, change this:
To this:
And then, I think, your options should work.
@TheDeadMedic:
The Settings API handles looking at any $POST data. That’s not the problem.
Regarding the default-settings updating on init, here’s my original, example code:
And here’s Mamaduka’s code:
Do you see the difference? There is a critical change from oenology_options_init() to ev_options_init(), to wit:
This:
Versus this:
Thus, in ev_options_init(), the function never actually does anything, because of the change.
The problem is they are getting saved… it’s just you’re always saving the defaults!
And that’s running on every page load (it’s hooked to the action
after_theme_setup
).Not to mention the
if
statement serves no purpose ($ev_options
will never befalse
).It seems you haven’t quite understood the Settings API. The whole point is so that you don’t need to save the options yourself, WordPress does it for you!
I’m sure you’ve checked out the Settings API already, although it is a little lacking. The following go into a little more detail, and also cover how to use the API to store options as an array.
I think I see the problem, Mamakuka.
You should be calling get_option(), not your defaults function, here:
This:
Should instead be this:
Otherwise, you’re doing as TheDeadMedic indicated: saving the default options on every init.