Why isn’t the following option getting saved?
Because the database option name (the second parameter for register_setting()
) is aa_myoption
, hence the input name
has to be aa_myoption
or in the array notation like aa_myoption[my_field]
:
<input name="aa_myoption"> <!-- like this -->
<input name="aa_myoption[my_field]"> <!-- or this -->
Secondly, when you retrieve the option value and when it is an array of settings (like the second <input>
above), and as with any other arrays, you should check if an array key exists before attempting to use the value:
<?php
$options = (array) get_option( 'aa_myoption', array() );
$my_field = isset( $options['my_field'] ) ? $options['my_field'] : '';
// Then for example when using checked():
?>
<input name="aa_myoption[my_field]" type="checkbox" value="myvalue"<?php checked( $my_field, 'myvalue' ); ?>>
<?php
// Or you can also use wp_parse_args() to make sure all KEYS are set:
$options = wp_parse_args( get_option( 'aa_myoption', array() ), array(
'my_field' => '',
) );
// Then for example when using checked():
?>
<input name="aa_myoption[my_field]" type="checkbox" value="myvalue"<?php checked( $options['my_field'], 'myvalue' ); ?>>
Additional notes
-
$my_field = isset( $options['my_field'] ) ? $options['my_field'] : '';
The empty string doesn’t necessarily need to be empty, we’re simply assigning a default value to
$my_field
when the array key/itemmy_field
doesn’t already exist, and you can even use the PHP 7 format —$my_field = $options['my_field'] ?? '';
which does the same thing as the one above. =) -
$options = (array) get_option( 'aa_myoption', array() );
A bit of explanation:
-
I’m telling
get_option()
to return an empty array if the option does not exist yet, i.e. the database queryWHERE option_name="aa_myoption"
returned no results. -
I’m type-casting the value to an array to make sure it’s indeed an array, because WordPress options (both custom and core options like
admin_email
) can be easily filtered by plugins and your own code.. e.g. via theoption_<option name>
hook, and it is possible that a plugin (or custom code) returned a non-array value.But of course, the best practice is for filter callbacks to always return the proper type of value.
And I removed the sample test cases from this answer, but you can always check them here. 😉
Also, I’d likely use the
wp_parse_args()
, but I’d probably create amy_theme_get_options()
function or something like that, which returns an array with options from the database and merged with the default values. 🙂
-