I’m using the Wrox WordPress plugin development book as a primary reference for getting started with a new plugin and I understand all settings can be saved as 1 array but the book does’t give an example of this and all the stuff I’m finding on the web seems so different from one example to another. The second half of a post by Konstantin gets me close but I’d really like to see a more complete example with multiple fields.
1 comment
Comments are closed.
Short answer: your
name
attribute values must use the schemaoption_name[array_key]
. So, when you use …… you get an array as option value in your validation function:
PHP does that for you, this is not a WordPress feature. 🙂
How to make that work with the settings API?
Let’s say, we want this options page, and all values should be stored in one option and validated in one function.
The options page
We need the hook
admin_menu
and two functions: one to register the page, one to render the output.The form
action
must beoptions.php
, or the validation will not be called. Look at the PHP source ofwp-admin/options-permalink.php
– there is a hidden trapdo_settings_sections('permalink');
– but it cannot work because the formaction
is wrong.Now, back to our custom page. We make it better than WordPress.
Register settings, sections and fields
We hook into
admin_init
when we need it and call a registration function.The important part here is:
$GLOBALS['pagenow']
must be eitheroptions-general.php
(for the output) oroptions.php
(for the validation). Do not call all of the following code on each request. Most tutorials and almost all plugins get this wrong.Okay, let’s register like crazy:
We fetch the option values for our page and parse them against some defaults. Pretty basic.
We register a settings group with the name
plugin:t5_sae_option_group
. I like prefixed names, they are easier to sort and to understand this way.Then we register two sections, 1 and 2.
And we add three sections, two for the first section, one for the second. We pass the option name and the escaped value to the callback functions for each field. Output handlers should not change data, just add some HTML.
All those callback handlers for the sections and fields will be called automatically when we call
do_settings_sections( 't5_sae_slug' );
in our page. We did that already, so we need just to …Print the fields
Note how the
name
attributes are built: the passedoption_name
is the first part, the array key follows in square brackets[]
.Oh, I introduced a function
t5_sae_debug_var()
. Here it is:Useful to see if we got what we expected.
Now, this works pretty well, we need just one thing:
Validate the option array
Because we used the bracket notation, our value is an array. We just have to walk through each element and validate it.
This is rather ugly; I wouldn’t use such code in production. But it does what it should: it returns a validated array of values. WordPress will serialize the array, store it under our option name in the database and return it unserialized, when we call
get_option()
.All of this works, but it is unnecessary complicated, we get markup from 1998 (
<tr valign="top">
), and many redundancies.Use the settings API when you have to. As an alternative use
admin_url( 'admin-post.php' )
as form action (look at its source) and create the complete settings page with your own, probably more elegant code.Actually, you have to do that when you write a network plugin, because the settings API doesn’t work there.
There are also some edge cases and incomplete parts I didn’t mention here – you will find them when you need them. 🙂