Adding options to WordPress plugins
Posted by Leonid Mamchenkov on August 15, 2007
Most WordPress plugins out there are simple things, fixing or changing one thing at a time. But there are also examples of more complex things, like e-commerce and banner management, advanced anti-SPAM control, more flexible content and user management, etc. One of the common things between those “advanced” plugins is that they almost always provide a user with a way to configure them – a screen with options.
In this post, we’ll see how to create plugins which integrate into WordPress options administration.
Let’s start with something simple first and work our way through. Here is a rather simplistic first version of the “Hello World” plugin that we’ll be expanding and and improving.
This plugin, when activated, provides a function say_hello() which will print ‘Hello world’ from where it is called. For the sake of the example, I use it for my sidebar. In the sidebar.php of my current theme I put these lines:
Here, I’m checking for the existence of my say_hello() function. If my plugin is deactivated, nothing will be printed out. If it is activated, and the function available, it will be called, and the output of it will appear in my sidebar. If I won’t check for the existence of the function, than chances are, I’ll get a nasty error message in my sidebar when the plugin is disabled. Obviously, I don’t want that.
OK. Now we have everything setup for our journey into Plugin Options Land. Let’s first modify the plugin to work with hardcoded options. We’ll add the interface later. Here is the second version of the plugin:
So, what happens here? First of all, I modified my say_hello() function to use two WordPress options – ‘hello_greeting‘, which I can use to change the greeting text to ‘hi’, ‘good morning’, or whatever I feel like, and ‘hello_target‘, which I can use to change ‘world’ to ‘me’, ‘admin’, universe’, or, again, whatever I feel like.
Then, I added a couple of functions – set_hello_options() and unset_hello_options() . I use this to, obviously, add and remove my options to WordPress options table.
And the last thing I added here is plugin activation and deactivation hooks. When my plugin is activated, options are added to WordPress database. When the plugin is deactivated, a cleanup is called and options are removed from the database. We saw how to do this before, in the automation with plugin post.
Under the hood changes don’t affect the result – I can still see the “Hello world” in my sidebar after plugin deactivation-activation, which is needed to set up options right.
So far so good. Now for the juicy stuff. How can we manage those plugin options of ours from within administration screens? The answer is simple. We’ll have to add a new screen to the Options area of the administration. We’ll need a sub-menu item (similar to ‘General’, ‘Writing’, and ‘Reading’ which are already there) under Options. That sub-menu item will point to our own options form, which will have our own logic and way of doing things.
How do we add a menu or sub-menu item to WordPress administration interface? Let’s see what Codex has to say about it. A quick search here and there and … yup … we have it! Adding Administration Menus page tells us all we need to know and more. It covers all the grounds – main menu items, sub-items, has a sample plugin, and this and that. Now I don’t even know why I’m writing this article anymore – that’s how good that page is… But people always tell me that I never finish anything, so just to prove them wrong, I’m going to finish this post anyway.
For the needs of our plugin, we need only one line out of that page. The one which shows the example of add_options_page() function call. Let’s see how it applies to our code in the third version of the plugin. (Note, that the code listing is getting long, so I’ll just skip the first part of the file – use line numbers for reference, if you need any. But you can simply append this code chunk to the one in the second version):
This might look a little confusing, but don’t let the looks of it set you off. Here is what happens. To modify WordPress administration menu, we have to hook to ‘admin_menu‘ action. Our plugin tells WordPress to call a function modify_menu() when the action ‘admin_menu‘ is executed. (You might want to pick a more unique name for a real life plugin, by the way) Our modify_menu() function can do all sorts of changes to the administration menu, but we need it to do only one – add a sub-menu to Options page.
To add a sub-menu to Options page we are using the add_options_page() function. I separated parameters to one per line with a little comment to make it easier to read. First parameter is used for the page title. Nothing important, so you can put anything in here. The second parameter specifies how we want our sub-menu item to be named. This is what will appear in the menu. The third parameter specifies which user level access or capability a user must have to be able to access this menu item. WordPress will hide the menu automatically from users who don’t have rights to access it. Now, the fourth and fifth parameters specify the file and function to call when the menu item is selected by the user.
These last two parameters give a lot of flexibility to how you want your plugin code organized. If you build something small and simple, like we are doing now, you probably would want to handle everything from a single file. Use __FILE__ as the name of the file for current file, and have a function that would handle all the administration stuff. If you have something more complex, you might want to have this Options screen stuff separated into a file of its own. Then you don’t have to specify the function – have all your logic in the file and that’s it. If you have something even more complex, you might want to use both the file and the function within it, to specify a precise place of where the options handling is happening. WordPress doesn’t limit you here in any way – it gives you the right to choose what’s the best approach for your task. This is one of those places that make WordPress so easy to appreciate.
Back to our example. From the code above you can see that I created an empty function admin_hello_options() which will be called when the user selects Options->Hello world menu item. Because my function is empty at the moment, not much fun will happen. Let’s see a screenshot, should we.
It’s all here – Options menu, Hello World sub-menu, an empty thing done by my empty function, and a standard WordPress footer. We are moving along just fine.
Now for the final step of our journey. We need to integrate our plugin, which supports options just fine, with the nice WordPress interface which we managed to find our way in. Again, I’ll try to keep things as simple and small as possible here.
First, let’s put some logic into our admin_hello_options() function. Here is one way to have it:
WordPress uses Cascading Style Sheets (CSS) to control how things look. So, to make our options blend in nicely, all we need to do is to use the same CSS classes as WordPress does in other Options screens. That’s why we wrap everything into a DIV with class “wrap“. And that’s why we use the H2 for the heading.
The logic of our options handling is pretty simple. If value were updated through the form, then save them in the database. Print the form to change the options in any case – whether they were just changed or not. That sounds like two functions and an IF statement. And that’s what we have in our function – a check for the submit button click, and two calls – one to update_hello_options() function, and another one to print_hello_form() function. Of course, you can skip all these functions and just through pieces together. But that’s not how I prefer it.
Now that we separated things, let’s look at them one at a time. update_hello_options() function may look something like this:
Check if each of the options was passed from the form, and if it was, save the new value to the database. If at least one option was updated, then print the OK message. If no options were updated, then something went really wrong (how could the form be submitted but not have any options defined in it?) and we should print the error message. Again, the classes are used the same way as I saw them on the other Options pages. (those fading messages are cool, aren’t they?)
The form printing function is not any more complicated. It’s a regular HTML form with some default values used from the WordPress options. Here is how the code looks:
That’s about all we need to make it work. Here is a screenshot of Options->Hello world as I see it now:
It’s not the most beautiful thing that I’ve seen in my life, but it sure works. The default option values are there, and if I type in the new ones, and click “Submit” button, I get a nice message telling me that everything worked OK, and my web site’s sidebar shows the new values.
All that remains now is a little beautification of the screen. I’ll leave it as exercise to you, since you probably will change the looks of it anyway. Just a hint – surround the Submit button with the paragraph of the “submit” class, and use table of class “optiontable” for the lining up of your option rows. There is also something about fieldsets there too, but as I said – that stuff is too easy to find on your own. (View HTML source from within your browser).
In exactly the same way you can add screens to some other main menu items. Instead of add_options_page() call add_management_page() to add a screen under Manage, or add_theme_page() to the a screen under Presentation, or add_user_page() to add a screen under Users.
This entry was posted on August 15, 2007 at 3:47 pm and is filed under Documentation, Menu, Options, Plugins, WordPress. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.