Tutorial Details
- Technology: WordPress
- Difficulty: Intermediate
- Estimated Completion Time: 30-45 Minutes
Final Product What You'll Be Creating
Creating themes to give away or sell is great, but not everyone who uses your theme will have a solid understanding of HTML/CSS. Providing your theme with an options page makes it easier for non-technical users to make theme changes without getting their hands dirty with code. I’ll show you how to make one from scratch!
What We’re Going to Achieve
Before we begin, what are we actually striving for? What are we going to make customizable about our theme? Well, this tutorial will focus mostly on the programmatic side, but in order to change something about the layout, we’ll need to have a few design ideas up our sleeves, as well. Here’s what we have:
- Change a theme’s color scheme
- Add 2x advertising spots
- Optional sidebar
- Optional recent tweets panel
- Optional search box
There are plenty of editable elements we could add to a theme, but after today’s tutorial which illustrates how to implement the five features listed above, you should have a good feel for how to create your own options page.
1. Creating the Required Files
We’re going to concentrate entirely on the options page first before we start making the theme change. First, we need a place to put all of our code that’s going to manage the options page. All this code is going to resides in a file called functions.php, which will go inside of our themes folder. So, if our theme is called ‘example,’ then the path to our functions file would be wp-content/themes/example/functions.php.
We don’t need to tell WordPress to include our functions.php file, it’s automatically called during the WordPress execution cycle.
2. Creating the Options Page
So first we need to actually create the blank options page – the canvas for our work. To do so, we must inform WordPress about the new options page that we wish to create. We accomplish this task by using actions. Actions are called at a specific time in WordPress’ execution; so, for example, when the menu in the dashboard is being created, the action admin_menu is called. We can tie functions to these actions; so we can execute our functions at specific times. Here’s the basic functions we need to create our options page.
<?php
// Options Page Functions
function themeoptions_admin_menu()
{
// here's where we add our theme options page link to the dashboard sidebar
add_theme_page("Theme Options", "Theme Options", 'edit_themes', basename(__FILE__), 'themeoptions_page');
}
function themeoptions_page()
{
// here is the main function that will generate our options page
}
add_action('admin_menu', 'themeoptions_admin_menu');
?>
Our first function, themeoptions_admin_menu is simply there to add a link to our page in the admin sidebar, it also tells WordPress what function to call to display the page which, in our case, is themeoptions_page().
The parameters for the add_theme_page() function are as follows:
- Page Title – Theme Options
- Menu Title – Theme Options
- Capability – edit_themes
- Handle – The current file
- Function – themeoptions_page()
If you have the theme activated, then, in the Themes drop down menu, you should see your new link to an options page which is currently blank. We now have the canvas for our options page, and we can begin implementing the forms, fields and back end of our options functionality.

3. Adding Options and Fields
Ok, so that page is looking a bit lonely; let’s add the form and fields that the user will interact with to make changes to the theme. It’s important to note you can style this page however you wish, even adding tabbed dialogs if you want; but for our tutorial, we’re going to make use of the default classes used by WordPress. This way it saves us the time of reinventing the wheel, and makes our options page blend in with the rest of the dashboard.
The code for our page should reside in our themeoptions_page() function, so we’re going to add our code in like this;
function themeoptions_page()
{
// here's the main function that will generate our options page
?>
<div class="wrap">
<div id="icon-themes" class="icon32"><br /></div>
<h2>Theme Options</h2>
<form method="POST" action="">
<input type="hidden" name="update_themeoptions" value="true" />
<p><input type="submit" name="search" value="Update Options" class="button" /></p>
</form>
</div>
<?php
}
First we create the predefined wrap class for the page. Then, we add a quick header with a default icon. Finally, our form; we need a hidden value so that we can check if it has been submitted. We also need a button that’s going to submit the form, and, again, we use a predefined class for this. Here’s what we have so far:

Now we have our basic structure. So if we check back to the beginning of this tutorial, we planned to implement five options.
- First of all, we’re going to allow the theme users to change the color scheme. For this, we’ll require a drop down list of color schemes available.
- Secondly, we’ll have two advertising spots. We’ll need two input fields for the image URLs, and two input fields for the links.
- Third is the optional sidebar: a simple check box.
- Fourth is the optional Twitter stream in the sidebar. We’ll need a checkbox and an input field for the username.
- Finally we’ll need an optional search box: another check box.
function themeoptions_page()
{
// here's the main function that will generate our options page
?>
<div class="wrap">
<div id="icon-themes" class="icon32"><br /></div>
<h2>Theme Options</h2>
<form method="POST" action="">
<input type="hidden" name="update_themeoptions" value="true" />
<h4>Colour Stylesheet To Use</h4>
<select name ="colour">
<option value="red">Red Stylesheet</option>
<option value="green">Green Stylesheet</option>
<option value="blue">Blue Stylesheet</option>
</select>
<h4>Advertising Spot #1</h4>
<p><input type="text" name="ad1image" id="ad1image" size="32" value=""/> Advert Image</p>
<p><input type="text" name="ad1url" id="ad1url" size="32" value=""/> Advert Link</p>
<h4>Advertising Spot #2</h4>
<p><input type="text" name="ad2image" id="ad2image" size="32" value=""/> Advert Image</p>
<p><input type="text" name="ad2url" id="ad2url" size="32" value=""/> Advert Link</p>
<h4><input type="checkbox" name="display_sidebar" id="display_sidebar" /> Display Sidebar</h4>
<h4><input type="checkbox" name="display_search" id="display_search" /> Display Search Box</h4>
<h4><input type="checkbox" name="display_twitter" id="display_twitter" /> Display Twitter Stream</h4>
<p><input type="text" name="twitter_username" id="twitter_username" size="32" value="" /> Twitter Username</p>
<p><input type="submit" name="search" value="Update Options" class="button" /></p>
</form>
</div>
<?php
}

4. Updating The Database
So far, we have an options page with a form that submits data to itself, via POST. The next logical step is to take the data submitted, and insert it into the WordPress database. To do so, we’re going to create a new function called themeoptions_update(). This function will be called by themeoptions_page(); so add this code to the very top of themeoptions_page();
if ( $_POST['update_themeoptions'] == 'true' ) { themeoptions_update(); }
Of course, the next step is to create the update function. Remember, for the sake of this tutorial, I’m not adding validation or sanitization to my code. When creating a plugin, you should always check the input from your users. However it’s beyond the scope of this tutorial. Now you could rely on WordPress to validate your input, but it’s best to do so yourself, to make sure.
Anywhere in the functions.php file, add this block of code:
function themeoptions_update()
{
// this is where validation would go
update_option('mytheme_colour', $_POST['colour']);
update_option('mytheme_ad1image', $_POST['ad1image']);
update_option('mytheme_ad1url', $_POST['ad1url']);
update_option('mytheme_ad2image', $_POST['ad2image']);
update_option('mytheme_ad2url', $_POST['ad2url']);
if ($_POST['display_sidebar']=='on') { $display = 'checked'; } else { $display = ''; }
update_option('mytheme_display_sidebar', $display);
if ($_POST['display_search']=='on') { $display = 'checked'; } else { $display = ''; }
update_option('mytheme_display_search', $display);
if ($_POST['display_twitter']=='on') { $display = 'checked'; } else { $display = ''; }
update_option('mytheme_display_twitter', $display);
update_option('mytheme_twitter_username', $_POST['twitter_username']);
}
The update function, as the name suggests, updates an option you can store in the database. If the option doesn’t exist, then WordPress creates it. We’ve prepended all our options with mytheme_, just to make sure we don’t overwrite options that another plugin/theme might be using.
So far, we have a settings page that can save our options, however, when we hit submit, and our options are stored, our form is blank when we re-visit it. This is because we need to load our values back from the database.
5. Fetching Options
We now need to fetch our options so that we can populate the settings form. This is an easy one, and we’ll do it by using the get_option() function. We could use variables, but for this example, we’ll simply echo the output of the function where it should go in the form. Our new code looks like this;
function themeoptions_page()
{
// here's the main function that will generate our options page
if ( $_POST['update_themeoptions'] == 'true' ) { themeoptions_update(); }
//if ( get_option() == "checked"
?>
<div class="wrap">
<div id="icon-themes" class="icon32"><br /></div>
<h2>Theme Options</h2>
<form method="POST" action="">
<input type="hidden" name="update_themeoptions" value="true" />
<h4>Colour Stylesheet To Use</h4>
<select name ="colour">
<?php $colour = get_option('mytheme_colour'); ?>
<option value="red" <?php if ($colour=='red') { echo 'selected'; } ?> >Red Stylesheet</option>
<option value="green" <?php if ($colour=='green') { echo 'selected'; } ?>>Green Stylesheet</option>
<option value="blue" <?php if ($colour=='blue') { echo 'selected'; } ?>>Blue Stylesheet</option>
</select>
<h4>Advertising Spot #1</h4>
<p><input type="text" name="ad1image" id="ad1image" size="32" value="<?php echo get_option('mytheme_ad1image'); ?>"/> Advert Image</p>
<p><input type="text" name="ad1url" id="ad1url" size="32" value="<?php echo get_option('mytheme_ad1url'); ?>"/> Advert Link</p>
<h4>Advertising Spot #2</h4>
<p><input type="text" name="ad2image" id="ad2image" size="32" value="<?php echo get_option('mytheme_ad2image'); ?>"/> Advert Image</p>
<p><input type="text" name="ad2url" id="ad2url" size="32" value="<?php echo get_option('mytheme_ad2url'); ?>"/> Advert Link</p>
<h4><input type="checkbox" name="display_sidebar" id="display_sidebar" <?php echo get_option('mytheme_display_sidebar'); ?> /> Display Sidebar</h4>
<h4><input type="checkbox" name="display_search" id="display_search" <?php echo get_option('mytheme_display_search'); ?> /> Display Search Box</h4>
<h4><input type="checkbox" name="display_twitter" id="display_twitter" <?php echo get_option('mytheme_display_twitter'); ?> /> Display Twitter Stream</h4>
<p><input type="text" name="twitter_username" id="twitter_username" size="32" value="<?php echo get_option('mytheme_twitter_username'); ?>" /> Twitter Username</p>
<p><input type="submit" name="search" value="Update Options" class="button" /></p>
</form>
</div>
<?php
}
So there you have it. The back end has now been completed. We’re able to update our options in the database, so all that’s left to do is make the theme react to these changes in the options page. This works similarly to how we updated the options fields: we fetch the option and then either display it or use it as a conditional to do something else. Let’s get started with the front end.
6. Changing the Theme
Changing the Colour Scheme
This is going to deal with CSS and such, which isn’t what this tutorial is about. So we’ll skim over how you’d approach this. One of the best ways to go about this is to have a default stylesheet that uses a colour scheme such as black, then a series of alternative colour schemes. For example style.css could style your layout black, but including red.css AFTER including style.css.
A helpful CSS tip is to use the !important tag. Use this tag in the stylesheets that change colours of the layout to ensure that those properties will, in fact, be used. In order to actually switch the stylesheets, add this code to the header.php file of your layout where the stylesheet would be included:
<link rel="stylesheet" href="<?php bloginfo('stylesheet_directory'); ?>/default.css" type="text/css">
<link rel="stylesheet" href="<?php bloginfo('stylesheet_directory'); ?>/<?php echo get_option('mytheme_colour'); ?>.css" type="text/css">
Adding advertising spots
This section is meant to show you the theory. In real life, you’d probably use a plugin or something like “Buy Sell Ads.” So say we’ve got two spots for our adverts to go in. Similar to above, we simply output the option where it needs to go, like so:
<a href="<?php echo get_option('mytheme_ad1url'); ?>"><img src="<?php echo get_option('mytheme_ad1image'); ?>" height="125" width="125" /></a>
<a href="<?php echo get_option('mytheme_ad2url'); ?>"><img src="<?php echo get_option('mytheme_ad2image'); ?>" height="125" width="125" /></a>
Optional Sidebar
This time, we’ll use the option as a conditional to decide whether or not we should output a block of code, that in this case would display a sidebar. Of course, your layout should be able to still display properly if a sidebar is not visible; so that one is up to you. The following code will be added wherever you’d usually call your sidebar, usually mine is called from header.php.
if ( get_option('mytheme_display_sidebar') == 'checked') { get_sidebar(); }
// or alternatively...
if ( get_option('mytheme_display_sidebar') == 'checked') { get_sidebar(); } else { /* display something else */ }
Optional Recent Tweets
For this little option, we’ll need to do two things. If tweets are enabled we’ll first need to display the area where the tweets should appear, we’ll also need to insert a block of JavaScript before the </body> tag to get the tweets from a specific user.
We need to place the following where we actually want the tweets to appear:
<?php if (get_option('mytheme_display_twitter') ) { ?>
<div id="twitter_div">
<ul id="twitter_update_list"></ul>
</div>
<?php } ?>
Next we need to place this code before the </body> tag, which most probably resides in footer.php;
<script src="http://twitter.com/javascripts/blogger.js"></script>
<script src="http://twitter.com/statuses/user_timeline/<?php echo get_option('mytheme_twitter_username'); ?>.json?callback=twitterCallback2&count=5"></script>
Tip: why not try and add your own option to change how many tweets are fetched above?
Optional Search Box
Finally, we come to our optional search box, which functions just as our sidebar did. We use the option as a conditional and display code dependent on the user’s choice.
if ( get_option('mytheme_display_search') == 'checked') { ?>
<form role="search" method="get" id="searchform" action="" >
<input type="text" value="" name="s" id="s" />
</form>
<?php }
Wrapping Up
I hope you’ve learned the basics of how to create an options page for your theme, and make it function properly. I’ve tried to skip a few of the tedious bits, like the actual CSS and the validation that should be in place, primarily because it was outside of the scope of this tutorial.
As usual, if you have any questions at all, leave a comment below! Thanks for reading!








jQuery Lightbox Evolution only $12.00
Events Calendar Pro - Wordpr ... only $30.00 
I should be first!
This is really useful, I am just about do a theme for client and thinking of offering a theme options so they can have some flexibility on the theme.
Thank you so much.
Hey Azizur, glad I came along at the right time – options pages give great flexibility to your theme and give clients another reason to pick and refer you =]
Having a nonce on the form would be good – http://codex.wordpress.org/WordPress_Nonces
Also, you don’t need to store each option separately. A single WP option would be fine, WP takes care of serializing/de-serializing the data. It is also helpful to make sure you give the option a good unique name – good post on this at http://dougal.gunters.org/blog/2009/12/10/wordpress-option-namespacing
Excellent article. This is incredibly useful as I get deeper into WordPress development. Loving 3.0 so far and this article inspires me to do more with UI options.
Good stuff, always nice to see you guys cover more of the professional side of theme development. Seems like you can’t call yourself a theme developer nowadays without adding things like a custom options screen.
Second!
This is a great tutorial, thanks for sharing!
Now, the Theme Options Page feature is a must when creating a custom theme for a client or even if you plan to release it for free.
This is a good tutorial for beginners.
An options page is definitely something that can make or break a theme, and when done well, their inclusion can improve the usability of customising a theme to a non-technical user.
Nice tutorial. I don’t want to spark a debate or a massive flaming session, and I use PHP myself, but I have to say that it’s pretty horrible mixing up markup and conditional stuff as in section 5. I’m not criticising your code, or this tutorial. I always cringe a little when I see it, that’s all
Thanks.
Haha yeah, different people different preferences =] I just prefer it that way for ease of implementation, glad you enjoyed nonetheless
Nice Tutorial! It’s a little advanced from me, but I’ll try it out and hopefully improve my skill set.
I think I’ve read and article on how to create an options page before. It wasn’t done in this particular fashion though. This one is well done though.
Great! Thank you very much, I’ll definitely use it.
I just wrote the same tutorial for another blog. I have a few issues with the way you went about doing your setup.
Firstly, you stored each value as it’s own option, that’s highly inefficient. You should make it an array and then store that to save time, space, and memory.
Secondly, you didn’t escape any of the values you retrieved from your form. Even if it is an admin page, it’s still susceptible to SQL injection.
Thirdly, you didn’t change the HTML of the page in any way after a settings update to let the user know that the form did work.
Fourthly, you’re not creating the options nor providing default values until the user submits the form.
Fifthly, (this isn’t a problem, but a personal annoyance) you’re checking for the hidden input inside the form on submit to run the settings update function instead of just checking for the submit button. since it’s impossible for the for the form to be submitted without the hidden input anyways, save yourself a line and a few characters and just check for the submit.
Thanks for the feedback Jonathan. This tutorial really wasn’t an in depth look at creating an amazing settings page, more a first resort for people new to the subject. For your first point, the reason I did this was more to get the point across about how to store and retrieve values. I could of just used a serialize function but that’s beyond the scope of the tutorial. Secondly I mentioned several times that sanitization was needed but also beyond the scope of the tutorial. Thirdly, that’s a pretty easy one that I skipped out on to not add fuzz to the tutorial, but it’s a good thing to have nonetheless. Fourthly again, more than what I was looking to teach. Fifth, that is just personal preference as I prefer to use hidden fields, after all a different form could submit to the page.
You’re right Dan, Nettuts is not a contest for who does the best tutorial ever.
If you’re that good in showing people how to make something, why not create your own tutorial website ? Or at least a book!
I am so annoyed when somebody thinks they’re smarter before reading the tutorial. Nobody is trying to show-off here, we’re just helping people learn. And some of us aren’t doing it for the 150$. You can have 10 to 100 times that money if you write a book on it.
There is no need for serializing in your plugin/theme code, WordPress takes care of that for you.
Hey Jonathan, I noticed you recreated a couple of Envato tutorials on your site, adding nothing to them except your site name.
We dont need hundreds of copies of the same tutorials on the net. Even if you change the tiniest detail.
bloat
Thank you for the great tutorial. I was looking for something like that so long. Now I will test it the next days. Looking forward for more …
With all due respect, there are quite a few How-to-make-an-option-page-Tutorials out there. Like most of them, you also neglected to mention WordPress’ Settings API, unfortunately.
Really great tutorial, Nettuts is the best, as its authors !
Excellent tutorial for beginners to add options page in wordpress admin.
Thanks for sharing.
great tutorial.. thank you for sharing this…
This actually a very helpful tutorial. Thanks for the effort Dan
Thanks, nice tutorial but there are some changes i would make.
1) Reset field
2) The submit button should have class “button-primary” (that’s what the rest of the WordPress settings uses for submitting)
3) Store all the options in an array (with default value, type, name…), inside of the themeoptions_page() do a foreach and depending on the type (text, select, radio…) add the proper html. Then when updating you do a foreach again on the options array and save it that way instead of adding update_option() for each option you make. Then in the theme files when you’re fetching the options do another foreach of the array and use the “variable variable” (not sure if that was the name, $$name) so you can get all the options like $mytheme_display_twitter, $mytheme_display_search.
4) When updating check if the field value is empty, if it is don’t do an update.
That’s all i could think of. I couldn’t explain the number 3 better in a comment, i’ll make a series on tutorials on theme options soon on my blog.
Anyway here is a screenshot of theme options i’m currently working and in the tutorials we’ll be making something like that. http://wpcanyon.com/pics/restyled.png
Is there any chance that Jeff will make a video on this, as video tutorials are easier to learn form.
thanks a lots
Yes, this is just what i needed.
Thank you.
Wew, great tuts….
Dan,
Very nice tutorial and very well done. One of the primary rules of a blog post is “never try to please everyone”. I prefer to write for the newbie in mind and let them develop their skills further towards perfection.
I am impressed that so many “so-called” experts have taken the effort to impress their skills upon the community as well. You have certainly touched on a subject that is of interest.
Keep up the great posts. My readers will enjoy it.
Cheers,
E.
Nice tutorial I can’t wait to get home to try it. This will help me with an idea I had for a theme that I am developing.
Thanks for this tutorial Dan. Now I’ll be able to implement an Options Page to all the free themes we’ll be releasing soon.
It’s been a great live saver….
Thanks for the tutorial mate!
Regards,
Avinash
Best tutorial ever made.. thanks
Hi. As a premium user is there a possibility to save a free tutorial as pdf, too? Like this one for example. I am a premium user, so I’m just curious if I could do this….
This is great. Can you teach us how to make the “Advert Image” an image upload field?
SO, this one is different then most of the option theme panels …
Nice JOB…
Great Tutorial. I am in the process of learning how to develop for WordPress, I learned so much from this tutorial. WHERE CAN I FIND MORE OF THIS?
Thanks for this fantastic tutorial. This is just what i needed to know for my new theme that I am developing! Nettuts to the rescue again!
This is the tutorial I have been looking for, I am just learning WordPress as I have come over from Code Igniter.
Everything once explained is really easy to do in wordpress.
I have debugging turned on and I get this message:
Notice: Undefined index: update_themeoptions in \wp-content\themes\projectf\functions.php on line 151
Any thought on how I can fix this?
Thanks, Dan,
this is the best tutorial on Theme Options I’ve ever found.
I owe you a beer
Is it possible to have two or more themes read the same custom options options?