Theme Options pages are growing in popularity among quality Wordpress themes. They provide the user with greater customization control over their website without having to know a hint of HTML or CSS. If you're a theme developer, user-friendliness should be one of the top things in your mind when you are creating a new theme for public use. You have to remember, not all of the people that use your theme are going to be as code-savvy as you, and thus you're going to have to accommodate to this. Theme Options pages are the perfect solution to this.
Theme Options pages do have their downside, however. In fact, it's for the complete opposite reason as above. It is true that not all of the people that use your theme are going to be as code-savvy as you, but the fact of the matter is, some of them will be!
For example, just the other day I downloaded a free theme to use for two of my small niche sites I'm cleaning up. Once I applied the theme, I immediately went to the sidebar.php file and started fiddling around with things; moving the searchbar, deleting adsense code, etc... If Theme Options had been built into the theme, odds are all of the stuff I was playing around with in the sidebar would not have been as easy to modify and change. Instead of seeing something like this where the searchbar should be:
<input class="search-input" type="text" value="Search" />
I am instead blown away with lines of unfamiliar php code.
In the end, however, a Theme Options page is a plus for any theme in my mind. As long as it's used in moderation, however. Don't go using php variables to add a picture of a taco or something in the sidebar, just embed the image in the sidebar php file. (Bad example, I know.) You get the idea.
Building a Theme Options Page
Alright. So you got your newly developed theme all ready to go. If you are designing a new theme yourself, I recommend that you actually have the theme done and coded in Wordpress before applying Theme Options to it. Just make sure the theme is working, there are no bugs, etc... This is one of the last things you should do when finalizing your theme. Trust me, it's much easier this way.
Step One
Lets begin. Make sure your theme has a functions.php file because that's where all the magic takes place. If your theme doesn't have one, go on and create one. Make sure to add the <?php and ?> tags to the beginning and end. Make sure there is no whitespace after the ?> or you'll break everything. Literally, you'll break everything in the world.
Once you have your functions.php file opened, you're going to want to paste the following code into it. I'll explain what's-what after.
/*Start of Theme Options*/ $themename = "Theme Name"; $shortname = "theme"; $options = array ( array( "name" => "Theme Name Options", "type" => "title"), array( "type" => "open"), array( "name" => "Header Stuff", "desc" => "Here is where you add stuff to the head tags.", "id" => $shortname."_header_stuff", "type" => "textarea", "std" => ""), array( "name" => "Footer Stuff", "desc" => "Here is where you add stuff to the end of the body tag.", "id" => $shortname."_footer_stuff", "type" => "textarea", "std" => ""), array( "type" => "close") );
Alright. Let's start looking more in-depth at this code. Oh, and, just to make a note. This is really the toughest part of creating a Theme Options page. The rest of this lesson is simple copy and pasting. Don't you feel better now?
/*Start of Theme Options*/ $themename = "Theme Name"; $shortname = "theme"; $options = array (
The above is somewhat easy to understand. Three variables are created: themename, shortname, and options. The variable themename is what it sounds like - the name of your theme. The variable shortname is sort of like a "nickname" for your theme. Make it short though. If your theme was called something like "ForTheLose.org Version Five Theme", make the shortname "ftlv5" or something similar. The reason you want it short is because you'll be using this variable value alot throughout this Theme Options process and you obviously don't want to have to keep retyping a long word. Another thing to note about the shortname variable is that it has to be one word. Make sure there are no spaces or weird characters.
The options variable begins our array, which is continued in the next part of the code.
array( "name" => "Theme Name Options", "type" => "title"),
This is the title of the Theme Options page itself. Your users will be greeted with this, so keep it simple. "Theme Name Options" or something short and sweet is fine.
array( "type" => "open"),
This opens up our array of options.
array( "name" => "Header Stuff", "desc" => "Here is where you add stuff to the head tags.", "id" => $shortname."_header_stuff", "type" => "textarea", "std" => ""), array( "name" => "Footer Stuff", "desc" => "Here is where you add stuff to the end of the body tag.", "id" => $shortname."_footer_stuff", "type" => "textarea", "std" => ""),
Alright, now we start getting into the cool stuff. The code above sets up two variables that you can use in your theme. The first one stores the information from a textarea into a variable called $shortname._header_stuff. (When you actually check for these variables in your theme files, $shortname. will be replaced with whatever value you entered in for your shortname variable a few steps up.)
If you're wondering what name, desc, id, type, and std stand for, keep on reading.
name - This is the title for this particular option.
desc - A description for the option.
id - This is very important. We will be using this to retrieve the variable value in the theme files.
std - This is the 'default' setting for the option. For example, if this was a checkbox, you could enter true or false here. True would be checked, and false would be unchecked.
type - This defines what type of option it is. You can have many types of input - checkboxes, textareas, input areas, dropdown menus, etc...
array( "type" => "close") );
This closes our array of options.
Step Two
Once you're done creating all of the options you want in your theme, you're going to have to style the Theme Options page. Don't worry, you don't actually have to do it, it's already done for you. You just have to paste the code. No modifying of this is necessary, just paste it right where you left off from before.
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_theme_page($themename." Options", "".$themename." Options", 'edit_themes', basename(__FILE__), 'mytheme_admin');
}
function mytheme_admin() {
global $themename, $shortname, $options;
if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings saved.</strong></p></div>';
if ( $_REQUEST['reset'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings reset.</strong></p></div>';
?>
<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:#eef5fb; padding:10px;">
<?php break;
case "close":
?>
</table><br />
<?php break;
case "title":
?>
<table width="100%" border="0" style="background-color:#dceefc; 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>
<?php
}The above code basically tells Wordpress what a Theme Options page is, what it looks like, and how it's used. Once you have that pasted, just paste this final line to execute the actual Theme Options page:
add_action('admin_menu', 'mytheme_add_admin');
You're almost done. Your Theme Options page is 100% created. Now you actually have to put the variables you just made to use!
Step Three
You're done with your functions.php file. You can wrap that baby up to go. Now you'll be dealing with all of your theme files, or at least the ones you'll be adding the adding your Theme Option snippets to.
Let me add this one important point that I learned the hard way. In whatever file you're editing now, whether it be sidebar.php or header.php or footer.php or whatever, make sure add the following code snippet somewhere on the page before you check for any of your Theme Option variables.
<? global $options; foreach ($options as $value) { if (get_settings( $value['id'] ) === FALSE) { $$value['id'] = $value['std']; } else { $$value['id'] = get_settings( $value['id'] ); } } ?>
Once you have that snippet pasted, you now have access to all of your variables just like you have access to Wordpress variables like the_content(); and bloginfo('template_url');.
Alright, example time. Say I had created a checkbox on my Theme Options page like so.
array( "name" => "Disable Breadcrumbs?", "desc" => "Check this box if you want to disable the breadcrumbs on the theme.", "id" => $shortname."_breadcrumb_disable", "type" => "checkbox", "std" => "false"),
First, I would navigate to my header.php file (or wherever my breadcrumbs code is located). After I pasted that important code from above somewhere in my header.php file, I would then check to see if the Disable Breadcrumbs checkbox was checked or not. If it is checked, I will tell Wordpress to display nothing. If it is checked, I will tell Wordpress to show the breadcrumbs. The code would look something like this:
<?if ($ftlv5_breadcrumb_disable == "false") { ?> <!--DO NOTHING--> <? } else { ?> <!--SHOW BREADCRUMBS--> <? } ?>
Another example would be if I had another option that was a text input rather than a checkbox.
array( "name" => "Welcome Message", "desc" => "Enter something as your welcome message.", "id" => $shortname."_welcome_message", "std" => "Welcome to my site.", "type" => "text"),
To show this variable in my theme, I would use echo like so:
<?php echo $ftlv5_welcome_message; ?>
Cool stuff no?
That's practically it. Now it's all up to you. Get creative with your Theme Options page. Make is something actually useful that will make the use of your theme that much more pleasant. But remember, don't overuse it! That could be as equally as frustrating.
I hope this tutorial was of some use for you. If it was, bookmark or subscribe to ForTheLose.org for more great posts like this! Thanks for reading.
If you liked this post, stay updated. Follow me on Twitter or subscribe to our RSS Feed via email.














I'll keep this in mind when I make Wordpress themes in the future...if I ever do. Very nice tutorial though, the more you post this kind of stuff the more interested I get into WP themes.
Eternal´s last blog post: Video Magic #9.