Try Tuts+ Premium, Get Cash Back!
How to Create a Better WordPress Options Panel

How to Create a Better WordPress Options Panel

Today, we’ll go through the entire process of creating an admin options panel for a WordPress theme, using the excellent WooFramework as an example. Then, we’ll take things a step further, as we implement jQuery to improve some of the functionality.

Tutorial Details

  • Program: WordPress
  • Version: 2.7, 2.8, 2.9 onwards
  • Difficulty: Intermediate
  • Estimated Completion Time: 1.5 hours
Final Product

WordPress is one of the most popular Content Management Software (CMS) systems out there. Whether it be for a client project or for selling themes on ThemeForest, WordPress is fast emerging as 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. Rather than having to open up the PHP template files and fiddling with the code, users can directly use the options panel to interact with your WordPress theme.

For example – if your theme has red, blue and green color schemes, and each has a corresponding CSS file, it would be far easier for a user to select their preferred color from a dropdown list. So today, let me guide you through the entire process of creating and enhancing a WordPress admin panel page inspired by Woo.

Step 1

Before we begin creating the admin panel, we need to have a theme, right? So download the source files provided with the tutorial. I’ve slightly modified the Classic WordPress theme. Place the ‘nettuts’ folder (I’ve named the theme ‘Nettuts’) in your wp-content/themes folder. You should see the following files:

  • functions.php (blank)
  • index.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 is going to be done within functions.php file.

A theme can optionally use a functions file, which resides in the theme subdirectory and is named functions.php. This file basically acts like a plugin, and if it is present in the theme you are using, it is automatically loaded during WordPress initialization (both for admin pages and external pages).

Suggested uses for this file:

  • Define functions used in several template files of your theme
  • Set up an admin screen, giving users options for colors, styles, and other aspects of your theme

(From the WP Codex)

Step 2

Now that we’ve got our WordPress theme set up, go to Appearance>Themes, and activate the nettuts theme.

Activated? Ok, great. Now we have to think of a layout for our admin panel page. Here’s the structure I’ve decided upon:

<div class="wrap rm_wrap">
	<div class="rm_opts">
		<form method="post">
			<div class="rm_section">
				<div class="rm_title> 
					<h3>Title</h3>
					<submit button>
				</div>
				<div class="rm_input rm_<select/textarea/text etc>">
					<input area>
					<description>
				</div>
			</div>
			
			/*Repeat the inputs for as many options as required. */
			/* use <div class="rm_section"> for each new section of inputs eg General, Home Page etc */
		</form>
	</div>			
</div>			

Let me explain all of that to you. The options set is going to be wrapped up into a div named “rm_wrap” and then “rm_opts” for the options. Then we start a form, with all the inputs within it. Each section of options(general Settings, Homepage settings, Blog settings etc) has a separate div with a class of “rm_section”. This div has a title (for the name) as well as several input divs within it. By using classes like <div class=”rm_input rm_select”>, we can style dropdowns, text inputs, and textareas differently.

Now, the most important thing is that the coding of this shouldn’t be done manually – we should use PHP’s flexibility as much as possible. That means efficiency: don’t code manually when you have loops for you!

Step 3

Begin by opening up functions.php in your favorite code editor (I use Notepad++). Enter the following code:

<?php

$themename = "Nettuts";
$shortname = "nt";

The two PHP variables hold the name of your theme (Nettuts in our case), and a shortname which you’ve defined (nt in our case). The shortname is used to prefix all our theme options names, and is usually unique to a particular theme. Moving on, we’ll write some code to automatically generate a list of WordPress categories, rather than having users type in ID numbers. Enter the code below under the already typed code:

$categories = get_categories('hide_empty=0&orderby=name');
$wp_cats = array();
foreach ($categories as $category_list ) {
       $wp_cats[$category_list->cat_ID] = $category_list->cat_name;
}
array_unshift($wp_cats, "Choose a category"); 

This snippet uses WordPress’ built-in get_categories function to fetch all categories, and then uses a foreach loop to store them in the variable $wp_cats. The options “Choose a category” is then added to the top of the array

Step 4

Now we start entering a list of options for the theme. See below, and paste it into your functions.php file:


$options = array (
 
array( "name" => $themename." Options",
	"type" => "title"),
 

array( "name" => "General",
	"type" => "section"),
array( "type" => "open"),
 
array( "name" => "Colour Scheme",
	"desc" => "Select the colour 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" => "Custom CSS",
	"desc" => "Want to add any custom CSS code? Put in here, and the rest is taken care of. This overrides any other stylesheets. eg: a.button{color:green}",
	"id" => $shortname."_custom_css",
	"type" => "textarea",
	"std" => ""),		
	
array( "type" => "close"),
array( "name" => "Homepage",
	"type" => "section"),
array( "type" => "open"),

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" => "Homepage featured category",
	"desc" => "Choose a category from which featured posts are drawn",
	"id" => $shortname."_feat_cat",
	"type" => "select",
	"options" => $wp_cats,
	"std" => "Choose a category"),
	

array( "type" => "close"),
array( "name" => "Footer",
	"type" => "section"),
array( "type" => "open"),
	
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" => "You can paste your Google Analytics or other tracking code in this box. This will be automatically added to the footer.",
	"id" => $shortname."_ga_code",
	"type" => "textarea",
	"std" => ""),	
	
array( "name" => "Custom Favicon",
	"desc" => "A favicon is a 16x16 pixel icon that represents your site; paste the URL to a .ico image that you want to use as the image",
	"id" => $shortname."_favicon",
	"type" => "text",
	"std" => get_bloginfo('url') ."/favicon.ico"),	
	
array( "name" => "Feedburner URL",
	"desc" => "Feedburner is a Google service that takes care of your RSS feed. 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")
 
);

That was a large chunk of code, which surely warrants some explanation. So here we go:

  • The PHP variable $options stores the entire list of options for the theme.
  • It is composed of a number of arrays, each with a “type” key to signify how it will be displayed, and what it does.
  • We start with a “type” => “title” array – this will be used to show the themename and a title at the top of the page
  • Each section (General, Homepage and Footer) has a separate list of options.
  • We start a new section by closing any previous sections, declaring a new section using array( "name" => "Footer",
    "type" => "section")
    and opening a new section.
  • Each option can have 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.

Step 5

Try navigating to WordPress. You will see that there’s no option anywhere to actually view the admin panel page; so how can we view it? 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: admin.php?page=functions.php&saved=true");
die;
 
} 
else if( 'reset' == $_REQUEST['action'] ) {
 
	foreach ($options as $value) {
		delete_option( $value['id'] ); }
 
	header("Location: admin.php?page=functions.php&reset=true");
die;
 
}
}
 
add_menu_page($themename, $themename, 'administrator', basename(__FILE__), 'mytheme_admin');
}

function mytheme_add_init() {

}

This function is meant for updating options, as well as adding a menu page. If the options are being saved (indicated by a hidden variable save), 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 menu page – the parameters are respectively, name and title, the user authorization level required to view the page, the save page and the function used for display/saving (called mytheme_admin in our case). See the mytheme_add_init, a blanbk function? Let that be, we’ll come to it later.

Step 6

Still no theme options page, right? Well, remember the mytheme_admim function we had talked about a few lines ago? We still haven’t written that function. So use the code from steps 6,7 and 8 to write that function. Starting off:

function mytheme_admin() {
 
global $themename, $shortname, $options;
$i=0;
 
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 rm_wrap">
<h2><?php echo $themename; ?> Settings</h2>
 
<div class="rm_opts">
<form method="post">

Pretty simple, right? If the options have been saved, write a message indicating so. Likewise for resets. You’ll notice a class=”updated fade” – WordPress will automatically fade this out in a few sections. Nifty, right? Moving on, we then start the “rm_wrap” div.

Step 7

Carrying on from above, paste in the following code:

<?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 class="rm_input rm_text">
	<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 class="clearfix"></div>
 
 </div>
<?php
break;
 
case 'textarea':
?>

<div class="rm_input rm_textarea">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
 	<textarea name="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" cols="" rows=""><?php if ( get_settings( $value['id'] ) != "") { echo stripslashes(get_settings( $value['id']) ); } else { echo $value['std']; } ?></textarea>
 <small><?php echo $value['desc']; ?></small><div class="clearfix"></div>
 
 </div>
  
<?php
break;
 
case 'select':
?>

<div class="rm_input rm_select">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
	
<select 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"'; } ?>><?php echo $option; ?></option><?php } ?>
</select>

	<small><?php echo $value['desc']; ?></small><div class="clearfix"></div>
</div>
<?php
break;
 
case "checkbox":
?>

<div class="rm_input rm_checkbox">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
	
<?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; ?> />
	<small><?php echo $value['desc']; ?></small><div class="clearfix"></div>
 </div>
<?php break; 

That is one large piece of code! Explanation – using a php foreach loop, each option type is evaluated on a case-by-case basis. We use a switch-case technique for this. The switch variable is the options – the cases are matched and evaluated. Notice the ‘break’ statement after each case? This is to prevent something known as the ‘fall-through’ property. When a case is matched, all successive cases are also executed. This means that if we match case 3, cases 4,5 etc. are also executed. We don’t wan’t that, right? So use a break to stop the switch-case.

If there is an “open” type option – nothing is done. If there is a “close” type options, two divs are closed. The “title” option is only used once – it is an introduction to the theme options. For each of the types “text” (input type=”text”), “select” (dropdowns), “checkbox” and “textarea” (its obvious what those mean), the corresponding input is displayed. Notice the <div class=”clearfix”> – it’s used for clearing floats, which we will do later.

Step 8

We’re coming to the end of that rather massive function. Paste in the code below:


case "section":

$i++;

?>

<div class="rm_section">
<div class="rm_title"><h3><img src="<?php bloginfo('template_directory')?>/functions/images/trans.gif" class="inactive" alt="""><?php echo $value['name']; ?></h3><span class="submit"><input name="save<?php echo $i; ?>" type="submit" value="Save changes" />
</span><div class="clearfix"></div></div>
<div class="rm_options">

 
<?php break;
 
}
}
?>
 
<input type="hidden" name="action" value="save" />
</form>
<form method="post">
<p class="submit">
<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
}

?>

For a “section” type option, I’ve used a counter variable $i. This keeps track of the sections number and conactenates it to the name of the submit button, to have unique submit buttons. There is also a last form at the end for resetting all options. The image used is going to be a transparent image used in our jQuery-fication. Use this very last piece of code to bring our functions into play:

<?php
add_action('admin_init', 'mytheme_add_init');
add_action('admin_menu', 'mytheme_add_admin');
?>

That tells WordPress to add the admin menu.

Step 9

And voila! We have our own awesome admin panel page with a separate menu position for itself. So let’s check it out – click the link. And yuck. That has got to be the most ugly admin panel page ever. So let’s call upon our good friend, CSS! Create a new folder in the nettuts/ directory and name it “functions”. Create a new CSS file there – functions.css. Paste in the following code:

.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;
	}

I won’t explain anything here; it’s pretty clear what each CSS declaration does, and you’re free to customize the layout for your own theme.

Step 10

So now we have a nice CSS file. But how do we add it to the page? After all, we don’t have direct access to the <head> of the document. Remember that blank mytheme_add_init() function we wrote in Step 4? That will come in handy. Change it to this:

function mytheme_add_init() {
$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.

Step 11

Go look at the page now. Pretty nice looking, isn’t it? But then, you ask, whats the ‘+’ icon for? Well, thats where jQuery comes in!. Create a new file rm_script.js in the nettuts/functions/ folder. Paste in the following code:

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').addClass('active').children('img').removeClass('inactive').addClass('active');
					
				}
			else
				{	jQuery(this).removeClass('active').addClass('inactive').children('img').removeClass('active').addClass('inactive');
				}
				
			jQuery(this).parent().next('.rm_options').slideToggle('slow');	
		});
});

What this does is – once the DOM loads, all the rm_options slide up. When the ‘+’ icon is clicked, the inactive class is removed from the image and the active class added – making it a ‘-’ icon. The reverse is done when the ‘-’ icon is clicked. The rm_options is then slid up or down(determined by the current CSS state) using the slideToggle function – pretty simple. To add this script, the same mytheme_add_init() function is used. Change it to:

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

The jQuery script will now be active. Gp check it out. Personally, I think its beautiful!

Step 12

Now that we have our theme options page all set up, I’ll just run you through using the options. The code to use the options is as follows:

$var = get_option('nt_colur_scheme');

That will fetch the nt_color_scheme options. See the examples below:

/* To change the CSS stylesheet depending on the chosen color */
<link rel="stylesheet" type="text/css"  href="<?php bloginfo('template_directory'); ?>/<?php echo get_option('nt_color_scheme'); ?>.css" /> 

/*To echo some footer copyright text, with HTML */
<p><?php echo stripslashes(get_option('bl_footer_text')); ?></p>

The variety of uses is limited only by your imagination.

Conclusion

I hope you’ve learned something in this tutorial. This isn’t your standard options panel. This one doesn’t use tables, it’s jQuery enhanced, uses awesome CSS, and is extremely easy to use. The point of this tutorial is to learn – you could always replace collapsible panels with tabs, for example, or even something more advanced. Use your creativity! Feel free to discuss or ask questions in the comments!

WooThemes has since released version two of their framework. You can review the details here.

Tags: Wordpress
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://gingahmail.com/ Gingah

    This really should be adopted as a part of the WordPress Codex, as virtually no other site has a run through of the process of doing this. Great article!

    • http://www.sneekdigital.co.uk Cristian Giordano

      Actually no, it shouldn’t be. Theme options ideally should be coded using WordPress’ Settings API (IMHO as that’s why they have it.)

      @link http://codex.wordpress.org/Settings_API

  • http://instant-webmaster.com Michael Robinson

    Thanks for this *Great* tutorial!

    I was able to create an options panel for my theme, using the functions. php example.

    Plus I was able to setup multisite functionality and create instant sites that use my theme.

    But I am having a problem getting the Administrator User Level to see the options panel for my theme; In the Admin Area I can see the [Appearances] tab and under it there are [themes] [widgets] [menus] [background] – But the [Theme Option Panel] does not appear…

    I did get the Options Panel to Appear for the Super Administrator, so I’m guessing that I need to somehow associate the Option Panel with the assigned user’s capability ( edit_theme_options) or Role (Administrator), but I don’t know how to do this, or if it is the correct approach.

    Can you include a quick example of how to give regular Admin Users access to the Options Panel in multisite mode?

    Best Regards,
    And thanks again for a Great Tutorial
    Michael Robinson

  • http://www.jacorre.com Josh

    Mike, I think you need to change the administrator setting in the following:

    add_menu_page($themename, $themename, ‘administrator’, basename(__FILE__), ‘mytheme_admin’

    to a different capability setting.

  • http://worldcruiseholidays.com David

    For you who have tried to put this code to work but didn’t work, there’s a bit of mistakes in the code of step 12. Step 12.
    First: $var = get_option(‘nt_colur_scheme’);
    It should be $var = get_option(‘nt_color_scheme’);

    Second:
    It should be

    The parameter of get_option is taken from the id in the array of step 4.

    to get this code: <link rel="stylesheet" type="text/css" href="/.css” /> to work, you need to create another css with the value of nt_color_scheme as filename (i.e: red.css)

    I just figured it out just now since I am new to this wordpress option panel. Hope it helps!

    David

  • http://dridgett.com.au David Walker

    Great tutorial. I’ve used it many, many times. At this stage I’ve started including an options panel like this in every project I do.

    However I now have a client that needs a wysiwyg field in the options panel. There is a section on the homepage where they want to be able to enter text, but also need to include bullet points and headings. I can’t really rely on them to type the html so I really need a wysiwyg in there.

    I know about the other options for doing this, such as using posts, extra fields, ect. But I would really rather include it in the options panel, as I already have other options relating to the homepage in there.

    Is there any way to do this?

  • Francz

    Great tutorial, I’ve managed to build in a bunch of SEO related functions for the theme but my client needs one field to use the rich text editor. Do I need to add code into the array for the function or do I add it to the code for the form build?

  • http://a022digital.com Andrew

    I’m having a bit of trouble adapting the $wp_cats function to work with a custom taxonomy.

    Has anyone had success generating a dropdown from a custom taxonomy?

  • dhanapal

    Hi friend,
    This is amazing tutorial.Thank you for sharing with us

  • Dave

    How do you make the options panel really make the changes, I installed the full template and changed some stuff. But the changes weren´t made on the site?!

    WHY?

  • Josefine

    Could you please write a part 2 on how to implement the options panel into wordpress.

  • http://cyberchimps.com Tyler

    First of all, thank you for an amazing tutorial. I just have one quick issue I would like to point out and hopefully get addressed. When working in debugging mode, a few errors come up with the code utilized here, particularly the code from step 5.

    The first comes with the following: “if ( $_GET['page'] == basename(__FILE__) ) {“. It seems that this is now depreciated, which I fixed using the following line instead: “if (( isset($_GET['page'])) && ($_GET['page'] == basename(__FILE__) )) {“. So, if anyone runs into the same issue, that is what I used to squash it.

    Now, the only other thing that is causing issues are the hidden variables “action” and “reset”, which generates two “Debug: Undefined index: action” and one “Debug: Undefined index: reset” errors. Is there a reason that these variables have to be hidden? Is there a way to define these which will allow the code to still function and allow it to pass the WordPress debugger? Thank you.

  • http://www.mimeocreative.com.au pHil

    Few small issues to fix:

    Remove the excess quotation mark on line 8 of part 8 (it’s on the alt attribute).
    In step 9, on lines 23 and 88, the value of the float property has doubled up.

    Also, you can delete all of those clearfix divs and just add ‘overflow: auto’ to the ‘rm_title’ class.

  • http://usermanualonline.net Nanta

    Wow, very great script. thanks for sharing dude. I will try it :)

  • http://sandeepthemaster.wordpress.com S Kumar

    Simply the best…. tutorial

  • http://www.secretdesign.me secretdesign

    Hi,

    this is one of the best things what I have found on internet about wp. I need to made custom post panel and then implement it in theme and that’s it.

    Thank you for grate tutorial and resources.

    Secret Design

  • Will

    Don’t work in 3.1.1, php 5.3.5, just doesn’t show in admin. Tried on 2 templates and your source, >source/final/nettuts/ otherwise template displays

  • http://www.shovan.org Shovan

    Hay, Thanks for article.. Helped me understand how to add options to admin panel.
    The only pbl I am facing is, I am using another frame work. The function.php side is perfect. I am confused how to code it in the web page currently I am using

    (This was adopted from the frame work I am using, This coded is from google analytics part)

    I am confused why $google is used and how I can change it?

    Cheers,
    Shovan S
    Web Designer

    t: http://www.twitter.com/ShovanSargunam
    f: http://www.facebook.com/ShovanSargunam
    w: http://www.shovan.org / http://www.thescube.com
    y: http://www.youtube.com/ShovanSurya
    l: http://www.linkedin.com/in/ShovanSargunam

  • http://cyberchimps.com Tyler Cunningham

    Sorry for the second comment, but I was wondering if you or anyone has attempted to make a version of this theme options page with tabs instead of the collapsable panels. I’ve been trying my hand at this for a few days as my theme has quite a few different options sections and I just can’t seem to get it right.

  • http://minimal.0fees.net/minimal Satish

    Nice tutorial but please can you make this tutorial as video tutorial :)

  • http://www.secretdesign.me secretdesign

    Hi,

    I have problem, I can not get featured category to work. All other work perfect but wit this I have problem.
    I did try both codes from page 2 and 3 here in comments but nothing don’t work.

    Thank you on help.

    • http://www.secretdesign.me secretedesign

      My mistake. All work perfect.

  • http://www.idev.co.in tapaswini

    Thanks for the great & sequential process.

  • http://www.rsatechnologies.in rakesh kumar

    i was developing some free wordpress templates and on that templates i was using some others work to define admin panel which is ugly and not properly arranged, This can help me a lot to arrange all that components properly. It is really a nice written tutorial. Do you people accept donations for such a good work?

  • http://www.llow.it Lorenzo

    I was trying the panel.Works perfectly but when i check the validation of my feed i noticed that the code has some problem.

    Using dreamweaver evidence invalid markup and verifying there is an issue on a form not closed well.

    Is there someone who has discovered the same problem ?

  • Emma

    hi – can i ask if this tutorial works for version 3.1 +

    if not can someone recommend me a good tutorial for beginners, in creating cms like features for my wp theme please?

  • http://jasoncalleiro.com Jason Calleiro

    This is such a good tutorial, I have a simple question though.. How do you guys figure this out?!?!.. I was looking at the wordpress codex and couldn’t find anything to really help me out to create an options panel.

    Really wanting to sharpen my theme crafting skills.

    Thanks!!!

  • http://www.thepdgroup.com Emma

    Hello. Great tutorial! Wanted to ask a quick question.. where you have used “mytheme” within the code examples, for example “mytheme_add_init”, “mytheme_admin”, mytheme_add_admin” – can we use anything in place of “mytheme”?? Also, does the word “mytheme” have to be consistent across all those little pieces of code with that word in? I.e. if i decided to write “mytheme_add_init” and then “otherWord_admin” elsewhere in the code, would that break things??

  • http://kevinw.de Kiwi

    Very, very great tutorial!
    That’s what I was looking for. It helped me to improve my theme developer skills a lot :)

    Best regards
    Kiwi

  • Ron

    you need to create a newer version for this tutorial :)

  • Anamika

    Thanks for the great tutorial. BTW how to add a color picker in this options panel?

  • http://portfolio.pixelngrain.com Jatin Soni

    This is really great tutorial with great script. It is very useful for person like me who is just entered into this field.

    Here everything is going well but I have few queries and issues needs to be solve with your great help.

    I have no problem with simple text and textarea field but getting lots of trouble in fact I dont know how to reflect category selection into my template/theme file. I need great help to solve this issue. I also don’t know how to call category latest post on that place with custom size thumbnail image and custom excerpt value of the post.

    Please help me to solve this. :)

  • http://portfolio.pixelngrain.com Jatin Soni

    One confusion please.. urgent help needed..

    As per your code ecactly I want to use css changer but dont know how to add tag into template so its call css accordingly… below the code now what code i should add to my theme file header.php to switch css

    array( “name” => “Colour Scheme”,
    “desc” => “Select the colour scheme for the theme”,
    “id” => $shortname.”_color_scheme”,
    “type” => “select”,
    “options” => array(“blue”, “red”, “green”),
    “std” => “blue”),

  • http://kroussi.com/blog K Roussi

    Information on this topic was SO difficult to find. I don’t know why this aspect of theming isn’t discussed more often. I’ve included this tutorial in my compilation of top theming resources.

  • http://overshapes.com Simeon Galabov

    Step 12 lacks a bit of explanation but nevertheless very useful and thorough tutorial.

  • Colin

    Your default value for elements doesn’t do anything. You never use it.

  • http://emc2innovation.com eric

    Ran into an interesting bug! I now use this tutorial as a base for my themes, and today I installed a few at the same time, in the same browser.

    After the first one ran its add_menu_page() for the first time, it put that theme’s name into the other two menu links.

    Took a bit to figure out, but I think it’s due to $themename being global. Couldn’t get it to fix, even after a cache clear – had to manually assign a value to $themename, then cleared it. Don’t think this should affect most people.

    Great tutorial. <3

  • http://www.sagive.co.il Sagive

    Hey.. i love it!!

    can anyone tell me how does the “overwrite” css box works ?
    Give me an example plz how to integrate ?

  • http://sammikhail.co.cc/ Samer

    Great tutorial, thanks a lot!

  • http://profitableintent.com Rubyfire

    Thank you thank you thank you! This is awesome and thank you soooo very much! I’m putting together my 1st wp theme and well this is awesome… lol thanks again man. Thanks again.

  • fraser

    Hi,

    Can anyone help?
    I’m not professional developer but Im looking for help in getting a media picker / media library to work in option panel. Id like to be able to pick images directly from the panel.

    thanks in advance

    Fraser

  • Nick

    What is the point of this tutorial? You tell us how to create an options panel but not how to make the options work on the theme?

    Sort of pointless.

  • Nick

    sorry I posted this comment on the wrong blog!!

  • http://www.niepes.com Roy Vincent

    woah! this is great having a full feature theme! thanks for this I found something new!

  • http://emc2innovation.com Eric

    That reset button sure is easy to hit. Watch out! Here’s a little addon to give you a bit of extra warning:

    Near the bottom of the final functions.php, replace the reset submit button:

    with this:

    Doing that adds an onclick event to the button, and changes it to a “button” instead of a “submit”. Then just after the final , place the following javascript:

    function confSubmit(form) {
    if (confirm(“Are you sure you want to reset everything?”)) {
    form.submit();
    }

    else {
    alert(“You decided to not submit the form!”);
    }
    }

    Your reset button then should rely on the user clicking “ok” in the dialog box that pops up in order to REALLY reset the form.

  • http://emc2innovation.com Eric

    That reset button sure is easy to hit. Watch out! Here’s a little addon to give you a bit of extra warning:

    Near the bottom of the final functions.php, replace the reset submit button:
    <input name=”reset” type=”submit” value=”Reset” />
    with this:

    <input name=”reset” type=”button” value=”Reset” onClick=”confSubmit(this.form);” />

    Doing that adds an onclick event to the button, and changes it to a “button” instead of a “submit”. Then just after the final </div>, place the following javascript:

    <script type=”text/javascript”>

    function confSubmit(form) {
    if (confirm(“Are you sure you want to reset everything?”)) {
    form.submit();
    }

    else {
    alert(“You decided to not submit the form!”);
    }
    }
    </script>

    Your reset button then should rely on the user clicking “ok” in the dialog box that pops up in order to REALLY reset the form.

  • http://www.secretdesignart.com Secret Design Art

    Hi,

    I have question. Now I wish to show more then one featured category and this don’t work.

    I used this:

    array( “name” => “Homepage featured category one”,
    “desc” => “Choose a category from which featured posts are drawn.”,
    “id” => $shortname.”_feat_cat_one”,
    “type” => “select”,
    “options” => $wp_cats,
    “std” => “Choose a category”),

    array( “name” => “Homepage featured category two”,
    “desc” => “Choose a category from which featured posts are drawn.”,
    “id” => $shortname.”_feat_cat_two”,
    “type” => “select”,
    “options” => $wp_cats,
    “std” => “Choose a category”),

    array( “name” => “Homepage featured category three”,
    “desc” => “Choose a category from which featured posts are drawn.”,
    “id” => $shortname.”_feat_cat_three”,
    “type” => “select”,
    “options” => $wp_cats,
    “std” => “Choose a category”),

    Can somebody help me?

    Thank you. ;)

  • http://www.komalthedesigner.com komal

    This was best tutorial for theme options, very easy and helpful.

  • Jason

    I’ve tried copying and pasting the code here from functions.php into my pre-existing functions.php file (at the end) and I get a White Screen of Death. I’ve uploaded the necessary folder as well into place. Anyone tried this and have a similar problem? What have I done. If I simply upload the code it’s fine. So I know it’s my fault :P

  • http://www.botaiusti.com Iusty

    This tutorial help me a lot, hope soon i will publish my first wp theme on themeforest

  • Dexter

    I’m new in creating wordpress themes and I’m wondering how would I move this to a separate file so that my functions.php would not contain that much code. I’m trying for a few hours now and I can’t seem to make it work.

    Thanks for your help guys!

  • Mark

    Hi,

    Is there a way to link to a specific section via an anchor tag.

    For example…

    I have made a custom menu in my WordPress sidebar. Currently in my Theme Options I have 4 sections (types).

    Basically, I want to make the custom menu link to a specific section, so when the user clicks the hyperlink in the sidebar, it then goes to the Theme Options page and automatically opens up the specific section that I want to open.

    So for example, if the 4th section had a Anchor tag of “open_me”. I could open it automatically using http://www.mydomain.com/wp-admin/admin.php?page=functions.php#open_me

    I hope this makes sense. Would love if someone could help me out on this one.

    Each section would need its own unique anchor tag, or other tag, however this is made possible, whether it be via anchor tags or something else.

    Thanks