This isn’t a terribly difficult task – it’s incredibly common, and it’s covered multiple places in the codex. So why am I writing about it? A few months ago, I was tasked with customizing a plugin – one that someone else wrote. I need to add some options to it, and their code was baffling to me. I could see that they were using custom options, but I couldnt understand how they were being set – it was like the author just made some form fields and hoped for the best.
What was happening is referenced here (Right in the codex – apparently the last place I thought to look). My first instinct has always been to post forms on an admin page to itself, then handle checking for the $_POST values, and creating/updating the appropriate options. As is often the case, WordPress makes it even easier than that:
I wont get into the boring details – you can look at the codex page for that – but pay special attention to the hidden fields you set up:
<input name="action" type="hidden" value="update" /> <input name="page_options" type="hidden" value="new_option_name,some_other_option,option_etc" />
Not too tough to understand – the first line tells the system that we’re going to be updating, and the second line lets WordPress know which fields we want to create/update. These, of course, need to match the “name” attribute of the input elements up above.
I posted a few days ago about the very cool functionality of maybe_serialize(), and its relation to WordPress options. I often store arrays in options, because they help keep the database free of unnecessary clutter, and they make your plugin even easier to use (from a developers view). I was a little worried that this “page options” trick would prevent me from saving arrays – but alas, WordPress saved the day again:
<input type="text" name="fruit_colors['apple']" value="red"> <input type="text" name="fruit_colors['carrot']" value="orange"> <input type="text" name="fruit_colors['banana']" value="yellow">
Just make a form field an array, like you would with a set of checkboxes (by adding [] after it). Pass in the proper values to the page_option hidden field, like so:
<input name="page_options" type="hidden" value="fruit_colors" />
This can get pretty interesting – a few days ago I used to to loop through categories and associate a string with each one – you can do the same for posts, days of the week, whatever suits your plugin.
So there you go. You’ve got yourself an option without any tinkering with $_POST variables, or checking if you need to update or create an option. WordPress even takes care of serializing it for you. What a world…
To be honest, a simple if statement on a value available globally isn’t going to be a bottleneck at all compared to all the other stuff that goes on when WP loads. Also, you can hook to admin_init to make sure it only happens on admin page loads.
To make sure that the correct form is also getting submitted and the user actually was accessing the form, you can use a combination of ‘check_admin_referer’ and ‘current_user_can’. I initially left those out of my description because I didn’t really feel like bogging down my approach. You should be using those things anyways, though, regardless of how you check for submission.
Could you release this as a bare bones sample plugin? It’s quite difficult to test and see what is going on here. Followed what you said and no luck getting this to work. Also, links to appropriate codex page referenced would be helpful too. Don’t mean to complain, thanks for taking time to introduce us to the concept.
May 24, 2009
The only problem with this approach is validation of the data that the user enters. You don’t get to do any. I usually just check for the appropriate $_POST variable in init, save the options appropriately, and then use a redirect to the admin page with an $_GET variable indicating an update happened.