How To Create An Options Page For Your WordPress Theme
WordPress is one of the most popular Content Management Systems. Also WordPress is a CMS of choice for many web developers It’s relatively easy to use, but can be made even simpler when you include an administration panel for users when making themes. Additionally, themes buyers find the options panel too easy to use rather than having to open up the PHP template files and fiddling with the code.
Today we will be incorporating an options panel for the WordPress Classic theme. The methods you will learn will allow you to very easily integrate it into an existing theme you’re working on.
Setting The Files :
The theme that we will be working on is the classic theme provided by wordpress. You can find it on wp-content/themes folder. You should see the following files:
- index.php
- functions.php
- comments.php
- footer.php
- header.php
- rtl.php
- sidebar.php
- style.css
- screenshot.png
- An images folder with two files
Most of our work will be done within the functions.php file.
Now go to your wordpress admin panel then go to Appearance>Themes and activate the classic theme.

Working on functions.php :
Begin by opening up functions.php in your code editor of the classic theme ( wp-content/themes/classic/functions.php ) then insert the following code :
<?php $themename = "Classic Theme"; $shortname = "ct";
I added two variables the first one reffers to the name of the theme and the second is the shortname : You can choose any name for these two variables but don’t forget to select significant names because you will be using them later.
Now let’s start adding some options for our theme :
$options = array (
array( "name" => $themename." Options",
"type" => "title"),
array( "type" => "open"),
array( "name" => "Color Scheme",
"desc" => "Select the color scheme for the theme",
"id" => $shortname."_color_scheme",
"type" => "select",
"options" => array("blue", "red", "green"),
"std" => "blue"),
array( "name" => "Logo URL",
"desc" => "Enter the link to your logo image",
"id" => $shortname."_logo",
"type" => "text",
"std" => ""),
array( "name" => "Homepage header image",
"desc" => "Enter the link to an image used for the homepage header.",
"id" => $shortname."_header_img",
"type" => "text",
"std" => ""),
array( "name" => "Footer copyright text",
"desc" => "Enter text used in the right side of the footer. It can be HTML",
"id" => $shortname."_footer_text",
"type" => "text",
"std" => ""),
array( "name" => "Google Analytics Code",
"desc" => "Paste your Google Analytics or other tracking code in this box.",
"id" => $shortname."_ga_code",
"type" => "textarea",
"std" => ""),
array( "name" => "Feedburner URL",
"desc" => "Paste your Feedburner URL here to let readers see it in your website",
"id" => $shortname."_feedburner",
"type" => "text",
"std" => get_bloginfo('rss2_url')),
array( "type" => "close"));
Here the variable “option” contains a big array which also contains other child arrays. Each child array holds an option.
The first array reffers to the title of the page ( In our case it’s ‘Classic Theme Options’ ). Every time when we want to add a new option we have to declare an array with a type and give it the name we want.
You can take a look at the options specified below :
- name: The name of the input field.
- desc: A short description explaining what it is to the user.
- id: the id of the field, prefixed by the shortname. It will be used to store as well as access the options.
- type: the input type – select, text or textarea
- options: used to declare an array of options for a select type input.
- std: the default input value, used if no other input is given.
Now we have our options ready but how can we view them ? Add the following pieces of code to the functions.php file:
function mytheme_add_admin() {
global $themename, $shortname, $options;
if ( $_GET['page'] == basename(__FILE__) ) {
if ( 'save' == $_REQUEST['action'] ) {
foreach ($options as $value) {
update_option( $value['id'], $_REQUEST[ $value['id'] ] ); }
foreach ($options as $value) {
if( isset( $_REQUEST[ $value['id'] ] ) ) { update_option( $value['id'], $_REQUEST[ $value['id'] ] ); } else { delete_option( $value['id'] ); } }
header("Location: themes.php?page=functions.php&saved=true");
die;
} else if( 'reset' == $_REQUEST['action'] ) {
foreach ($options as $value) {
delete_option( $value['id'] ); }
header("Location: themes.php?page=functions.php&reset=true");
die;
}
}
add_menu_page($themename." Options", "".$themename." Options", 'edit_themes', basename(__FILE__), 'mytheme_admin');
}
Here I declared a function with a name of “mytheme_add_admin”. This function is used for updating options : If the options are saved, then all the options are updated with their new values. If the options are being reset (indicated by another hidden variable with a value reset), then all of the options are deleted. The last line adds a theme page( add_theme_page ) in Appearance box and it calls mytheme_admin function. If you want you can replace add_theme_page with add_menu_page to create an external box :

At this step we still don’t have the theme options page, so we have to write mytheme_admin function which was called by add_theme_page, add this code to functions.php :
function mytheme_admin() {
global $themename, $shortname, $options;
if ( $_REQUEST['saved'] ) echo '<div id="message"><p><strong>'.$themename.' settings saved.</strong></p></div>';
if ( $_REQUEST['reset'] ) echo '<div id="message"><p><strong>'.$themename.' settings reset.</strong></p></div>';
?>
Here we have some conditions : if the settings are saved WordPress will show ” Classic theme settings saved “. Likewise for reset.
Now paste the code above I will explain it after :
<div class="wrap">
<h2><?php echo $themename; ?> Settings</h2>
<form method="post">
<?php foreach ($options as $value) {
switch ( $value['type'] ) {
case "open":
?>
<table width="100%" border="0" style="background-color:#cdcdcd; padding:10px;">
<?php break;
case "close":
?>
</table><br />
<?php break;
case "title":
?>
<table width="100%" border="0" style="background-color:#868686; padding:5px 10px;"><tr>
<td colspan="2"><h3 style="font-family:Georgia,'Times New Roman',Times,serif;"><?php echo $value['name']; ?></h3></td>
</tr>
<?php break;
case 'text':
?>
<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><input style="width:400px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?>" /></td>
</tr>
<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;"> </td></tr><tr><td colspan="2"> </td></tr>
<?php
break;
case 'textarea':
?>
<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><textarea name="<?php echo $value['id']; ?>" style="width:400px; height:200px;" type="<?php echo $value['type']; ?>" cols="" rows=""><?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?></textarea></td>
</tr>
<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;"> </td></tr><tr><td colspan="2"> </td></tr>
<?php
break;
case 'select':
?>
<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>"><?php foreach ($value['options'] as $option) { ?><option<?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option><?php } ?></select></td>
</tr>
<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;"> </td></tr><tr><td colspan="2"> </td></tr>
<?php
break;
case "checkbox":
?>
<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><?php if(get_option($value['id'])){ $checked = "checked=\"checked\""; }else{ $checked = "";} ?>
<input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> />
</td>
</tr>
<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;"> </td></tr><tr><td colspan="2"> </td></tr>
<?php break;
}
}
?>
<p class="submit">
<input name="save" type="submit" value="Save changes" />
<input type="hidden" name="action" value="save" />
</p>
</form>
<form method="post">
<p class="submit">
<input name="reset" type="submit" value="Reset" />
<input type="hidden" name="action" value="reset" />
</p>
</form>
</div>
Explanation :
With this code we created our options page content : I used a php foreach loop, each option type is evaluated on a case-by-case basis. So if the type of the option is title do this, if it is a checkbox do that…
If there is an “open” type option we do nothing. If there is a “close” type options, we close our table. For each of the types “text” , “select” , “checkbox” and “textarea” , we display the corresponding input. At the end we added two buttons one to save the settings and the other to reset them.
Now our options page is ready, but we have to add this short code to make it work :
<?php
}
add_action('admin_menu', 'mytheme_add_admin');
?>
This short code tells WordPress to add the admin menu.
After all this, here the result you should end up with :

In this example I used simple styles included in functions.php to make our options page looks better but I will show you how to add a stylesheet to functions.php so you can add your styles rapidly.
How to add a stylesheet to functions.php :
First, you have to create a new folder on your theme folder, name it functions then create a new css file with a name of functions.css. After flling your css file add this code to functions.php after mytheme_add_admin function :
function mytheme_add_style() {
$file_dir=get_bloginfo('template_directory');
wp_enqueue_style("functions", $file_dir."/functions/functions.css", false, "1.0", "all");
}
That adds the functions.css file to the head. The location of the file is determined by the template directory.
Also, if you want you can use scripts to make your options page better by including a js file.To do this you have to change
wp_enqueue_style("functions", $file_dir."/functions/functions.css", false, "1.0", "all");
To :
wp_enqueue_script("script", $file_dir."/functions/script.js", false, "1.0");
After adding your stylesheet or your script, you have to add this code under add_action(‘admin_menu’, ‘mytheme_add_admin’); so they will be active :
add_action('admin_init', 'mytheme_add_init');
Making Use of the Options :
Now after creating our options, I will show you how to make use of them. First up, open up your header.php file, and add the following code:
<?php
global $options;
foreach ($options as $value) {
if (get_settings( $value['id'] ) === FALSE) { $$value['id'] = $value['std']; } else { $$value['id'] = get_settings( $value['id'] ); }
}
?>
You must put the code above at the start of all the files which you add options to. Once you’ve done that you can begin using your options. For example : If you want to display the footer text you have to echo $ct_footer_text ( ct reffers to the shortname of the theme ) :
<?php echo $ct_footer_text; ?>
For a checkbox you can check if the box is checked ( it will return true ) do this…
You can download the functions.php file here.
That’s it ! Thanks for reading this tutorial and I hope it was useful.
Did you enjoy this article and found it useful?
Get even more from us:








Gleenk
Posted 244 days ago 28Is there a way to add an image-upload field? How can i do?
Burke
Posted 264 days ago 27Thanks so much. I followed this tutorial a few months back and it worked fine. Now when I save the options, they save, but I get the message on a white next page:
“You do not have sufficient permissions to access this page.”
How do I stop this from happening?
Joseph
Posted 140 days ago 37I fixed this by editing the two instants of header where it says
header(“Location: themes.php?page=functions.php&saved=true”);
to point to you page URL, in my case:
header(“Location: admin.php?page=admin-options-page.php&saved=true”);
James
Posted 282 days ago 25So much better than other tutorials on how to do this. Yours is more organized and easier the read. Thank you. ^^
James
Posted 282 days ago 24I was trying to follow this tutorial: http://wpshout.com/create-an-advanced-options-page-in-wordpress/ and let me just tell you that yours is far superior. It’s easier to read and understand and much easier/quicker to follow the steps. Had this up and running in like 30 mins. I spend my entire day yesterday trying to figure out that nutjobs tutorial. Thank you, so much.
Chris
Posted 316 days ago 23Thankyou sir..Created my first theme option panel today. And it looks great!
Naupad
Posted 323 days ago 22The tutorial is good but If I already have a theme options page in the parent theme and want my own customizations in the child theme, how can I create a theme options page for child theme as common functions like mytheme_add_admin would conflict with those in parent theme and raise error….
Help….
TimeStampYourPosts
Posted 356 days ago 20So, when was this blog post written? I can’t see a time stamp anywhere so I don’t know if this is out of date or not.
Rean John Uehara
Posted 356 days ago 21May 21, 2010. :|
Hasitha @ BlogsTemplates.NET
Posted 264 days ago 26+1 for that.
wparena
Posted 417 days ago 19Thanks! I’ve been getting those errors in a couple of little websites. Now I know what the heck is going on and have written on it also
Alexander Theis
Posted 505 days ago 17Hi this is a really nice guide. But i have following problem.
If I click on Save or Reset i will get an error.
“Warning: Cannot modify header information – headers already sent by… ”
Does anybody know something about it? Error is in this line
“header(“Location: themes.php?page=functions.php&saved=true”);”
“header(“Location: themes.php?page=functions.php&reset=true”);
dev
Posted 542 days ago 16great tutorial thanks :)
Ravi
Posted 634 days ago 15Great tutorial.
Thank you for sharing :)
@Scott Corgan,
“header already sent” error is most probable because you have few empty lines in functions.php file
remove all empty lines from functions.php file and error should be gone.
Scott Corgan
Posted 688 days ago 14Having issues with “header already sent” any ideas?
Thanks.
Sean Thompson
Posted 468 days ago 18Functions.php is very touchy. In PHP you cant have any blank lines. So take out any blank lines and you should be good.
riesurya
Posted 721 days ago 13clearly explained tutorial. I’ll try in my next WP theme.
Naeem
Posted 730 days ago 12Very nice article, a must bookmark!
.-= Naeem´s last blog ..10 Best of Breed CSS Editors =-.
WordPress 101
Posted 731 days ago 11Great tutorial! Options pages are becoming almost required for anyone who customizes themes, or creates WordPress sites for their clients. Tweeted and shared this with my WordPress 101 members. Thanks again!
Hein
Posted 731 days ago 10Nice and helpful guide, great job. definitely going to use this ;)
.-= Hein ´s last blog ..Getting started with pdf generation in PHP =-.
Jordan Walker
Posted 731 days ago 9Great way to add customization to the administration section of wordpress for customers to update themes and other options.
Sumeet Chawla
Posted 731 days ago 8Just the thing I wanted! Thank you very much for the share… We can create very complex option pages depending on the theme I guess…
.-= Sumeet Chawla´s last blog ..Formwork Company =-.
Jean-Baptiste Jung
Posted 732 days ago 7Great tutorial! I used to write a similar post one or two years ago but yours is most complete and up to date. Keep ut the great job!
.-= Jean-Baptiste Jung´s last blog ..Thematic WordPress Theme Toolbox: 10 extremely useful hooks =-.
Auré
Posted 732 days ago 6Interresting article, thanks for sharing :)
Konstantin
Posted 733 days ago 5I’m sorry, but I don’t like it at all.
Have you ever heard of WordPress’ Settings API?
Maybe you want to get familiar with the WordPress Core before you write tutorials that … are no good.
Patrick Offczorz
Posted 734 days ago 4Great Tutorial. That’s exactly what I was looking for. Thanks m8
nay
Posted 734 days ago 3HI fri., thanks your training and tutorials. I really got experience for your tutorials. May be you too get a lot of knowledge and share to all other peoples.
Mike Smith
Posted 734 days ago 2Nice tutorial. I’m definitely going to have to try using these codes and tweaking them to fit my needs. Thanks for posting this up.
.-= Mike Smith´s last blog ..Sneak peek of our Picture Perfect theme =-.
Matt @ Theme Thesis
Posted 734 days ago 1Sweeeet. It’s nice to see all these options page tutorials creeping up now. When I first learned how to do them the resources around were so scarce, it was brutal. This is very nicely written, good job!
.-= Matt @ Theme Thesis´s last blog ..How to Easily Change Thesis Skins =-.