Just another WordPress site

How to build an options page for your WordPress theme (In 5 easy steps!)

Posted by on Apr 12, 2010

First things first. An options panel is a custom set of options that are user definable and that come as part of a theme. Typical uses would be allowing users to change the background color of the entire site or add their social network ids to some images without having to edit any php.

Theme options are now a must if you are thinking of selling premium WordPress themes but as well as that they’re also pretty darn cool!

We are going to build theme options that allow users to add their Youtube, Twitter, Facebook and MySpace urls to some images. This sort of functionality is sought after in a theme as it negates the need for extra plugins.

Step 1 – Set up your options

Open up functions.php (or create it if your theme doesn’t have one yet). We will be making all the magic happen with functions.php.

Copy the following code in to it

<?php
$themename = "Jealous  Designs";
$shortname = "JD";
$options = array (
array(    "name" => "Social Networks",
"type" => "section"),
array( "type" => "open"),
array(    "name" => "YouTube ID",
"desc" => "ie If your Youtube url is http://www.youtube.com/jealousdesigns, put jealousdesigns",
"id" => $shortname."_social_youtube",
"std" => "",
"type" => "text"),
array(    "name" => "Twitter ID",
"desc" => "ie @_a_n_d_y",
"id" => $shortname."_social_twitter",
"std" => "",
"type" => "text"),
array(    "name" => "Facebook ID",
"desc" => "What ever comes after facebook.com for your profile or page. Ie If your url is http://www.facebook.com/pages/Jealous-Designs/234553006051 you would enter pages/Jealous-Designs/234553006051",
"id" => $shortname."_social_facebook",
"std" => "",
"type" => "text"),
array(    "name" => "Myspace ID",
"desc" => "What ever appears after myspace.com for your profile.",
"id" => $shortname."_social_myspace",
"std" => "",
"type" => "text"),
array( "type" => "close")
);

What this has done is set up the options that we are going to offer the user but now before we have defined our theme name and shortname.

Next up we want to add these options to the WordPress backend as theme options.

Step 2 – Give your theme an options panel

Still in functions.php.

Copy the following code in to it

<?php
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');
}
?>

In a nutshell this snippet adds functionality to enable us save the options and then adds the actual page through the add_theme_page function.

Step 3 – Add the options to your new panel!

So far we have set up the options we want to offer the user and given the options a page to be displayed on, now we need to get those options on to that page!

<?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>';
?>
<div class="wrap rm_wrap">
<h2><?php echo $themename; ?> Settings</h2>
<div class="rm_opts">
<form method="post">

The above code opens a function called mytheme_admin, declares the variables we set up at the top and checks to see if it needs to display a message. (This is done through a GET request.)

After that it opens up a div, displays a title, opens an inner div and begins the form that will ultimately save all of our options.

Next up we need to access and display the options we set up earlier. The below code does just that.

<?php foreach ($options as $value) {
switch ( $value['type'] ) {
case "open":
?>
<?php break;
case "close":
?>
</div>
</div>
<br />
<?php break;
case "title":
?>
<p>To easily use the <?php echo $themename;?> theme, you can use the menu below.</p>
<?php break;
case 'text':
?>
<div>
<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
<input name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "") { echo stripslashes(get_settings( $value['id'])  ); } else { echo $value['std']; } ?>" />
<small><?php echo $value['desc']; ?></small><div></div>
</div>
<?php
break;
case "section":
$i++;
?>
<div>
<div><h3><img src="<?php bloginfo('template_directory')?>/functions/images/trans.gif" alt="""><?php echo $value['name']; ?></h3><span><input name="save<?php echo $i; ?>" type="submit" value="Save changes" />
</span><div></div></div>
<div>
<?php break;
}
}
?>

Essentially what this code does is loop through the options we set up at the top and display different html according to the type value in the array.

Finally we close the form and add a reset button to the bottom of the page.

<input type="hidden" name="action" value="save" />
</form>
<form method="post">
<p>
<input name="reset" type="submit" value="Reset" />
<input type="hidden" name="action" value="reset" />
</p>
</form>
<div style="font-size:9px; margin-bottom:10px;">Icons: <a href="http://www.woothemes.com/2009/09/woofunction/">WooFunction</a></div>
</div>
<?php
}

Save your functions.php.

Step 4 – Add some style

You can upload your functions.php now and check it out but you won’t like it! I warned you.

What it needs is a bit of css and a bit of jquery!

So. Here is the css. Open up a new css file. Dont add it to your existing style.css as we only want these styles applied to our options page, not our whole theme.

.rm_wrap{
width:740px;
}
.rm_section{
border:1px solid #ddd;
border-bottom:0;
background:#f9f9f9;
}
.rm_opts label{
font-size:12px;
font-weight:700;
width:200px;
display:block;
float:left;
}
.rm_input {
padding:30px 10px;
border-bottom:1px solid #ddd;
border-top:1px solid #fff;
}
.rm_opts small{
display:block;
float:right;
width:200px;
color:#999;
}
.rm_opts input[type="text"], .rm_opts select{
width:280px;
font-size:12px;
padding:4px;
color:#333;
line-height:1em;
background:#f3f3f3;
}
.rm_input input:focus, .rm_input textarea:focus{
background:#fff;
}
.rm_input textarea{
width:280px;
height:175px;
font-size:12px;
padding:4px;
color:#333;
line-height:1.5em;
background:#f3f3f3;
}
.rm_title h3 {
cursor:pointer;
font-size:1em;
text-transform: uppercase;
margin:0;
font-weight:bold;
color:#232323;
float:left;
width:80%;
padding:14px 4px;
}
.rm_title{
cursor:pointer;
border-bottom:1px solid #ddd;
background:#eee;
padding:0;
}
.rm_title h3 img.inactive{
margin:-8px 10px 0 2px;
width:32px;
height:32px;
background:url('images/pointer.png') no-repeat 0 0;
float:left;
-moz-border-radius:6px;
border:1px solid #ccc;
}
.rm_title h3 img.active{
margin:-8px 10px 0 2px;
width:32px;
height:32px;
background:url('images/pointer.png') no-repeat  0 -32px;
float:left;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border:1px solid #ccc;
}
.rm_title h3:hover img{
border:1px solid #999;
}
.rm_title span.submit{
display:block;
float:right;
margin:0;
padding:0;
width:15%;
padding:14px 0;
}
.clearfix{
clear:both;
}
.rm_table th, .rm_table td{
border:1px solid #bbb;
padding:10px;
text-align:center;
}
.rm_table th, .rm_table td.feature{
border-color:#888;
}

Save this as functions.css in the root of your themes directory (wp-content/theme_name/functions.css)

Next we need to add some jquery goodness to it. Open a new javascript file and copy this code in to it.

jQuery(document).ready(function(){
jQuery('.rm_options').slideUp();
jQuery('.rm_section h3').click(function(){
if(jQuery(this).parent().next('.rm_options').css('display')=='none')
{    jQuery(this).removeClass('inactive');
jQuery(this).addClass('active');
jQuery(this).children('img').removeClass('inactive');
jQuery(this).children('img').addClass('active');
}
else
{    jQuery(this).removeClass('active');
jQuery(this).addClass('inactive');
jQuery(this).children('img').removeClass('active');
jQuery(this).children('img').addClass('inactive');
}
jQuery(this).parent().next('.rm_options').slideToggle('slow');
});
});

Save this as theme_options.js in a js folder in your theme directory (wp-content/theme_name/js/theme_options.js)

Finally we need to initiate these styles on the page.

Open up functions.php again and add the following code.

function mytheme_add_init() {
$file_dir=get_bloginfo('template_directory');
wp_enqueue_style("functions", $file_dir."/functions.css", false, "1.0", "all");
wp_enqueue_script("theme_options", $file_dir."/js/theme_options.js", false, "1.0");
}

Quite simply this function adds the stylesheet and the jquery to the header of the theme options page. (Woo!)

Last but absolutely not least there are two image that we need to add to the page for the css to grab.

Download pointer.png and trans.png

Add them to your images folder of your theme (wp-content/theme_name/images/pointer.png)

Step 5 – Upload and enjoy!

Upload functions.php, functions.css, theme_options.js and the two images. Log in to your WordPress dashboard.

Voila!

Have fun!

Leave a Comment