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
  • Faisal

    i have just downloaded and check your provided nettus wp theme, its the same issue here. Theme option page is working fine in admin panel. Butt its effect is not appearing any where in the theme.

  • http://www.rvoodoo.com Rev. Voodoo

    thanks to this tutorial, my entire theme has been overhauled. Every single piece of the theme is able to be swapped out by user. It’s pretty damn cool. Next up, 5 different colour schemes. But two issues I had with the menus. Only 1 real problem. First, the request…. when you use the menu to select images or whatever, the entire path to the object is displayed. Which means my option menu has to be hella wide to see the whole path, usually some gets cut off. Is there a way to cut the path, just show the file name?

    Next up is the problem. Whenever using code in the menu….(the analytics portion for example) you can input the code just fine….and with stripslashes used in the theme, it works perfectly. However when you go back to the menu, part of the code is still in the code box, and part has broken off into outside of the code box. So if you update options elsewhere, any code in any box is now broken. You then have to go back into the code boxes and delete the remaining broken code to empty the box to and save again to fix the problem.

    So basically when you enter the code and save its good, but if you ever go back into that menu, it breaks.

    Any ideas? Is this just on my end? Everything else works perfectly, and I’m lovin it!

  • http://www.digitalraindrops.net Adeptris

    I have used this is a theme subfolder to offer 20 text or add blocks, to use as shortcodes or in a widget.

    This is in the twenty Ten WordPress 3 theme, you can download it free here to see a working example.

    http://www.digitalraindrops.net/index.php/theme-addtext-for-wordpress/

    This page and the author are credited.

    David

  • http://www.der-prinz.com Michael Oeser

    I use this for all of my themes now and customers just love it. It´s great optionspanel and of course I added a credit link to this page into the optionspage of my themes.

    Just one thing that would make it even more userfriendly: It would be perfect if an opened section would not close once the user clicked “save”. I wasn´t able to figure it out by myself so any help would be appreciated.

    • http://nine95.com Michael Pedzotti

      Michael,

      I have modified a plugin using the code given in this tutorial and that was one of the first features I thought needed to be added. It is a little complicated but involves adding an ID to the Section type in Step 4, putting a checkbox in the code that builds the section title (Step 7) and wrapping some PHP around it all to make it respond to the appropriate inputs. The status of the checkbox (which is saved as an option if ticked) determines the startup state of each section (expanded or not) by configuring the class (active/inactive) of the image element and following options div.

      If you are interested I can extract the code segments and you can make of them what you will :-)

      • http://www.michaeloeser.de Michael Oeser

        Michael P.

        a little late but I am very interested. Can you send via email. I would put a link to your site (if you want) when I add this function to my themes.

        Thanks
        Michael O.

      • http://www.intellectdesign.co.uk Wagner Matos

        Hi Michael,

        Do you think you could send me the code segments for keeping the section open?

        Thanks mate!
        Wagner

  • Pierre Wiberg

    Hi, nice tutorial!

    But finding problem saving the changes I make.
    I’m trying to ad a logo, the script in the functions file is

    array( “name” => “Logo URL”,
    “desc” => “http:// link to you cusom logo”,
    “id” => $shortname.”_logo”,
    “type” => “text”,
    “std” => “”),

    and the script in the header.php is

    <a href="/”><img src="” alt=”"/>

    When I save it in the admin panel nothing happens. It closes the panel and when I open it again, the link to the imgage is not there anymore. and no changes are made on the website.

    What to do?

    Please help if you know how to solve this!

  • http://www.digitalraindrops.net Adeptris

    I would do something like this, I have added tilde ‘~’ so it is seen as text, you would need to remove them!
    This is not tested so test on a local install :-)

    &lt;~img src=&quot;" 
    alt="" /&gt;
            &lt;~a href=&quot;/"&gt;</a>
    

    Try without the tilde

    &lt;img src=&quot;" 
    alt="" /&gt;
            &lt;a href=&quot;/"&gt;</a>
    

    David

  • http://digitalraindrops.net/ Adeptris

    DUH!

    Download the theme on the page in the link below, it has all you need to look at, there is code to add different theme background, headers, slideshows, page colours, menu colors etc:, per page using this menu tutorial to update theme options or page meta.
    http://www.digitalraindrops.net/index.php/plasticity-theme-beta-release/

    I was working on this when Version 3 came out the ‘Twenty Ten’ theme uses WordPress built in thumbnail support to allow a different header per page, you might want to look at that!

    David

    • http://www.antsmagazine.com Nahid

      fix up the link david

  • Sean

    Looks like I’m a little late to the party with this one… but can anyone suggest a reason that this function.php (which I have mostly just copy and pasted from here) wouldn’t be loading my functions.css?

    I have this code in the right place

    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″);
    }

    and the file is sitting right there in the functions folder.

    • http://www.webdesign-bureau-of-mauritius.com Sachin

      Hi Sean,
      late reply but anyway, it should be called “functions.php”.

  • Jenny

    Amazing tutorial, thanks so much! Have to start playing around with this now :)

  • http://www.wpexplorer.com AJ

    You never explained how to show the custom CSS.

    • http://web-gab.com ciprian

      Indeed! No explinations of how to implement custom CSS. Anyways, great tutorial! Thanks

  • Jenny

    This whole thing works like a charm!!!

    I had this idea how to add more functionality, but I have no clue how to do it, maybe one of you does:

    Depending on which color scheme is selected I want to display different other options, i.e. modify color of certain sections in one style that don’t exist in the other. But every way I tried to implement some sort of IF statements in the code broke the whole thing (as expected, but I tried anyway).

    Any idea how this could be done?

    Thanks a lot in advance!

    • http://www.digitalraindrops.net Adeptris

      You could do this by if statements but it would mean hardcoding all the variables etc:

      I have used this admin tutorial on a test theme as proof of concept, it is a free downloadable theme, in the headers section a function is called which loads the colors by page number, which can be set in the admin settings area, for each page you can choose different elements to change.

      This is loaded into an array and passed as a temporary style and applied to the elements styles.

      Feel free to download the theme which is meant as a learning aid, so you can take any code samples and use them however you want.

      http://digitalraindrops.net/2010/06/plasticity-theme-beta-release/

      David

  • teddy

    Hello,
    Excellent work thank you. I am French, to sadden for my English.
    My problem, I would like to post(show) extract him(it) from a comment on my index.php page, I manage well to select in the administration and to post(show) the title of the category:

    But how post(show) the extract of the comment of the category selectionner in the admin. Thank you for your work.

  • MWM

    Thanks for this great tuts!

    But I want to know how to add wp_dropdown_pages() options just like get_categories() in your post?

    thanks before

  • http://www.wpsecurity.com Sam

    Will upgrading WordPress affect the custom admin page?

    Does anything get over-written if WP is upgraded automatically?

    Thanks much,

    Sam

  • Guy

    Great tutorial it has made my theme much better. However I have a small issue and I think it might relate to the wp_enqueue_script wp_enqueue_style section of the code.
    I have my theme set up locally using xampp on two computers, one at home and one at work. The theme options section works beautifully at work but the js and css is not called on my set up at home. The theme files are identical (I have checked and rewritten repeatedly) but I can not get the options page to work properly at home.
    Can anyone help me out with this? Is it an enqueue script issue or something else? I am pulling my hair out.

  • http://www.cplus.co Cplus

    Hi, This is awesome.

    But how can I add childpage to mail control panel. I mean, we created a new div on control panel as $themename. So I want to add a child menu on. How?

    Thanks.

  • http://wpclubs.com WPClubs

    Thanks, i’m going to give it a try.

  • Akshay

    The Problem I’m facing is that when I activate the the theme, the default theme options are not loaded.Is there any way to fix this.

    Pls reply ASAP

  • http://tenebroso.net Jon

    A million thank you’s. This tutorial was very, very helpful. I used it to allow people to select the category of posts that display on the front page, along with choosing from a set of options for the quantity that displays. Then I called the custom post query like this:

    <?php
    $cat = get_option(‘dwp_feat_cat’);
    $quantity = get_option(‘dwp_feat_quantity’);
    $args = array(
    ‘posts_per_page’ => $quantity,
    ‘category_name’ => $cat
    );
    query_posts($args); if (have_posts()) : ?>

    <?php while (have_posts()) : the_post(); ?>

    • http://web-gab.com ciprian

      This is a great note! It helped me understand how to actually implement it into wordpress. But do you have any ideea how to make it work the custom css?

  • Nick

    This is sexy and efficient. The only problem is that it’s stubborn when it comes to implementing it into my own theme. I have tried many different ways and I just can’t get it to work, specifically the CSS. It loads everything in a very “small” way and doesn’t include jQuery, either. How can I fix this?

    • http://bp-tricks.com Bowe Frankema

      Could be because you are making a Child Theme? You should then replace the TEMPLATEDIRECTORY for STYLESHEETDIRECTORY. Then it loads fine :)

      Awesome tutorial guys!

  • Kent

    Hi,
    Don’t know if anyone has already mentioned this but, the CSS is a bit buggy when this is used in IE 8(unsurprisingly…). When the headings are opened the backgrounds begin to dissappear, and when closed the design begins to break entirely.

    A quick fix to this is to add the line “overflow: hidden;” to the rm_section class in the functions.css file.
    :D

  • Michael

    Beautiful, and very very useful… Thankyou!

  • http://bradlangdon.co.uk Brad

    I used this method on a local theme I am developing just to try it out.

    But then after deleting all of the relevant files and relevant code from the functions file the nettuts menu is still showing up in the back end no matter what I do.

    I have cleared all browser history, cache etc and it has been over a week and the menus are still there.

  • http://digitalraindrops.net Adeptris

    I am getting a few visitors from this post, but the links on my website hane changed so they come up as broken links.

    Many thatnks to NetTuts and the author, as I have used the code several times, the latest as part of a set of over twenty tutorial posts, these are using a twenty ten child theme so the template vs stylesheet links are resolved, the tutorials create this theme.
    http://tutorial-2.digitalraindrops.net/

    The theme uses a variant of the options page, and returns values for the info panel in the header, the social media icons, the post heading on the main page, and the footer credit bar at the bottom.

    To help visitors work through the starting child theme is downloadable, then for each step the files are also downloadable.

    The ones that use the options page code are, options page, social media, header panel, main page and footer, if anyone follows these they should have a good understanding of how to use the code from this tutorial in a theme, setting and getting values.

    Novice with no code skills should start here and work towards the second set:
    http://digitalraindrops.net/templates/

    Intermediate with a little php, css, html skills, and a local wordpress with database start here:
    http://digitalraindrops.net/templates-two/

    Anyone else can just grab any files from the downloads page and read selective posts:
    http://digitalraindrops.net/downloads/

    Hope this helps the visitors that are arriving at my website from broken links in these comments.

    David :)

  • The J

    Great tut!
    I would suggest adding an “isset” check for every $_GET, $_REQUEST, $_POST action, as php throws a notice for every time it hasn’t been done.
    It’s just a good php habit that can save time in case of debug.
    Also, for what concerns WP, “get_settings” is a deprecated function since v.2.5…. please use get_option instead :)

  • Adrian

    Hi there, I tried to add a submenu but I can’t !
    Can someone show me how to add a submenu to this theme panel ?
    Thanks !

  • Adrian

    ON IE 8, the jquery crashes for the last 2 sliding panels ! :(

  • http://nine95.com Michael Pedzotti

    Rohan, I am grateful for the detailed tutorial. I have extracted the code and adapted it for a plugin options page I have been working on. The options page now looks great (apart from when viewed in IE8). Thanks again for the detailed code listing and instructions, even though it is for a theme, it works just as well, with some adaptations, in a plugin.

  • http://web2clone.com Saroj

    Thanks a lot…..

  • http://downloadtaky.info Downloadtaky

    I’m trying to follow your (fantastic) instructions and I’m almost ready to publish my new template.
    What I’m not able to do is to let users choose how many column they want to have in their template.
    I’ve created a function called: $dwn_number_column but I’m not able to use it to choose how many sidebars show.
    If you wanna take a look to what I’ve wrote please take a look here:
    http://downloadtaky.info/index.txt
    http://downloadtaky.info/functions.txt

  • http://www.twentyeleven.co.uk TwentyEleven

    How the hell did I miss this tut. This is something i’ve been trying to get my head around for ages and will definitely be used in every client project of mine.

  • http://dmaggio.carbonmade.com Aldi

    Hi! Thanks for the great tute!!

    Anyway, I was wondering if you could tell me how I can make two input fields under one option name?

    For example, an option called ‘Name’ with two separate fields: ‘first name’ and ‘last name’.

    How can I make that work under one option name?

    Thanks in advanced! Cheers!

  • http://www.speckygeek.com Pritam

    The above code will give error in wordPress (I have tried it.) and the theme will not get past the review process on WordPress.org. I have scrubbed this code and improved it to meet WordPress 3.0 requirements. http://www.speckygeek.com/create-wordpress-theme-options-page/

    • http://www.koalamedia.es koalamedia

      hi,
      How can i show a custom taxonomies dropdown for choosing a “featured category”?
      I have:
      array( “name” => “Homepage featured category”,
      “desc” => “Choose a category from which featured posts are drawn”,
      “id” => $shortname.”_feat_cat”,
      “type” => “select”,
      “options” => $wp_tax,
      “std” => “Choose a category”), ……

      and use this to load the taxonomies, but doesn’t work :

      $args=array(
      ‘name’ => ‘Catalogs’ //”Catalogs” is my custom taxonomy
      );
      $output = ‘names’; // or objects
      $taxonomies = get_taxonomies($args,$output);

      $wp_tax = array();
      foreach ($taxonomies as $category_list ) {
      $wp_tax[$category_list->ID] = $category_list->name;
      }
      array_unshift($wp_tax, “Choose a category”);

      What its wrong? :(

      thk, great tutorial

    • Wujekgreg

      Thanks :) you solved my problem :D

  • http://www.almogdesign.net Almog

    How do I retrieve the data or echo it, I add a for each loop

    function get_custom_option ($name) {
    global $options;
    foreach ($options as $opt_key => $opt_val) {
    if ($opt_val['name'] == $name) {
    echo $opt_val['id'];
    return;
    }
    }
    }

    and I’m trying to echo the data like so

    But all I’m getting is the short name and array name not that the saved data. Can someone help me with this.

  • http://www.prowordpress.net/ feyt

    Thanks your great article

  • http://kapilchugh.wordpress.com/ Kapil chugh

    Really awesome one.Thanks for this.

  • laureenc

    Great tutorial! I have implemented it my theme, but had to call it as an additional functions file (user-functions.php) Im new to this, but now when i save an option, even though it works, it redirects back to the dashboard. Any suggestions to get it to the right place? Thanks!

    • laureenc

      Oops, figured it out :-)

      • http://goldstudios.net Adam Goldschmidt

        How did you figure this out? Happens to me too.

        By the way, Awesome tutorial – I have completely changed the look of it and some of it features and it looks awesome! The only problem is that it redirects to WP dashboard – Didn’t figure this out yet..

  • http://www.bloggingjunction.com/ Saksham

    I had a question.

    array( “name” => “Use A Custom Logo”,
    “desc” => “Check the box if you want to use a custom logo.”,
    “id” => $shortname.”_logo_check”,
    “type” => “checkbox”,
    “std” => “”),

    Can you please recode it so that the check box is checked by default if the user has not manually unchecked it?

    • http://frankiejarrett.com Frankie Jarrett

      @Saksham

      I had a similar dilema. In the end, I decided to rephrase my options to better fit the functionality instead of trying to change the functionality itself.

      As a matter of principal in your case, I would say that if you’re really wanting this to be checked by default, then it is hardly a “custom” logo option, and the default logo would hardly be “default” ;)

      My real advice would be to leave this option as-is. If the user wants a “custom logo” it shouldn’t be the default, they need to check a box for such custom things :)

      All principals aside, if you really want to “Using A Custom Logo” by default, then in your situation, I might use something like:

      array( “name” => “Disable Custom Logo”,
      “desc” => “Check the box if you do not want to use your own logo.”,
      “id” => $shortname.”_logo_check”,
      “type” => “checkbox”,
      “std” => “”),

      Hope that change of perspective helps in some way. If you find a better solution please share it!

      //Frankie

  • http://wptheming.com Devin

    I created a base options panel that can be used with almost theme. It has a different design and additional options, but it still based on the same sort of options array. Video demo and code available here if anyone wants to check it out: http://wptheming.com/2010/12/options-framework/

  • http://digitalraindrops.net Adeptris

    I have a few visitors to my website from here looking for a working example, I have now used this script on many themes.

    However with the latest WordPress preferences there is a move away from update_option() and get_option() to register_setting() which stores the values in a single serialized array option.

    Time for an updated example, this twenty ten child theme creates other child themes and allows you to edit the style.css in real time, using 132 style color elements as options.

    It is downloadable and functionable and might give an overview of setting and using an options array.
    http://digitalraindrops.net/2010/12/child-theme-creator/

    It is based on the above code in this post but has additional functions now required if you submit a theme to WordPress.org, you need to use isset(), register_setting() and a validation function for the form inputs.

    A WordPres accepted (November 2010) theme written by me that uses these with a modified version of this script, can be found here:
    http://wordpress.org/extend/themes/atmosphere-2010

    Hope this helps in updating code practices for the Options Page

    David

    • Nicolas

      Validation is missing in almost every Option page tutorial. Your theme is quite intersting to undertand how it works. Thx!

  • Aravona

    Really nice tutorial, I spent hours looking for something that explains this kind of process.

    How do I get it to look at my CSS? I get the php side of things easily, and I looked at using:

    $var = get_option(‘nt_colur_scheme’);

    as well as:

    <link rel="stylesheet" type="text/css" href="/skins/skin_/style.css” />

    However the css doesn’t load, I think I maybe putting the variable in the wrong place, where do you actually put that variable in order for it to make an effect?

    Cheers,

    Ara

  • http://studio@stylique David Jon

    Awesome tutorial thanks a bunch.

    However I’m having one major issue. I can’t get the checkbox to function correctly. I’ve looked at it a couple of times, but can’t find the problem. If someone could look at the code, maybe somebody else can see it. BTW i’m working on WordPress 3.0.4….

    This is the array……

    array( “name” => “Show Posts?”,
    “desc” => “Show the Posts panel in Admin”,
    “id” => $shortname.”_show_posts”,
    “std” => false,
    “type” => “checkbox”),

    And this is the code for the form.

    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;

    If it looks a tad bit different then your code, youre right. I combined a couple of different tuts together.

    All the other input field so far work fine, however i actually only tested the textarea and text input fields.

    • David Jon

      stupid me forgot to mention what the problem was…..

      The checkbox displays fine, but the value doesnt stay after saving. Also when I echo the outcome in my template it renders value ‘on’, however i thought i gave it value=’true’ in the code…..

      • miniMAC

        Hi! I have the same problem! If you find a solution, please answer me :)

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

    Awesome tutorial….

  • http://www.spanischer-fussball.de Rafa

    Thank you a lot for this really useful tutorial!

  • http://www.greatsayings.net Great Sayings

    A must read tutorial for novice Theme developer! Thanks a ton for this article ! Can i use this source/files for my themes which i want to sell online!

    • Mike

      I think we should be ! I m using this code for my themes with a little modification!

      What do u Think Guys ?

      I’m planning to sell some of theme in themeforest too! Admin please response to this! Will be grateful if you can remove our doubts!

  • Olof Lid

    Hi!

    This is a great tutorial and I really like it, and I’ve used it for quite some time now. Yesterday I came up with the idea to control my slideshow via a page in my options menu, and I thought of saving the options as an array, but I really can’t come up with a good solution for this. I thought of serializing my array, but I don’t know where and how in the process I should do it.

    If anyone please could point me in the right direction, it’d be much appreciated!

  • http://www.ragunaru.com Ragnar

    Hmm, I have no idea where I went wrong with this but I’m getting a blank page after updating/saving a post or a page.Trying to figure out where the error is but no luck so far. All works fine if I remove all the functions relating to the admin panel.

    A huge thanks for that article, though, this is insanely educating and useful.

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

      yeah there you need to make tad changes so that it works fine try to ob_start() at the beginning and at end of the function it may work

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

        Yeah there you need to make tad changes so that it works fine try to ob_start() at the beginning and add Ob_end_flush at end of the function it may work

  • http://www.papersoup.org Brixter

    They forgot to implement the options in the frontend.

    if ( get_option( ‘plp_contact_us’ ) )
    {
    define( ‘panadolPressSettingsContactUs’, get_option( ‘plp_contact_us’ ) );
    }
    else
    {
    define( ‘panadolPressSettingsContactUs’, ‘Contact Us’ );
    }

    echo panadolPressSettingsContactUs;

  • http://www.mushindesign.co.uk Martin

    Hi this is a great tut but I have one question on a problem I’m getting.

    When I click ‘Save changes’ it takes me to a page which says ‘You do not have sufficient permissions to access this page.’ however the options DO get updated, and this is on my own custom theme, so it’s really just an annoyance having this error page whenever I make a change as it still works.

    I have downloaded the source files and the code is exactly the same, I have installed the source files theme, which works perfectly with no permissions error.

    Anyone have any ideas what the problem might be?

    Thanks

    • http://www.mushindesign.co.uk Martin

      Ah never mind, got it :D

      • eric

        Martin, what was the problem? I’ve run into the same thing :(

  • http://www.mushindesign.co.uk Martin

    Could anyone give me some pointers on how I would go about changing the menu position of the options panel. So I could have it maybe above the ‘Appearance’ option or even within it?

    Thanks