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

    I have the panel working however i dont understand where the last two pieces of code gets put in order for the settings to take effect.

    The panel itself looks fantastic and is simple to use however I am just confused how to implement the changes using the code:

    $var = get_option(‘nt_colur_scheme’);

    /* To change the CSS stylesheet depending on the chosen color */
    <link rel="stylesheet" type="text/css" href="/.css” />

    /*To echo some footer copyright text, with HTML */

    Any help would be gratefully received..

    • http://andor1995.info/ Nagy Andor

      Use it like this,

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

      For me it works this way. I hope this helps.

      Regards, Andor Nagy

  • http://www.flintandtinder.co.uk Adam

    I’m with Phil on this. Ideally I’d like to use the values inputed in the fields anywhere across the site. I’ve tried using but it doesn't seem to work.

    • http://www.flintandtinder.co.uk Adam

      Code not displayed above should have been:

      • http://www.flintandtinder.co.uk Adam

        <?php echo get_option( $show, $default ); ?>

  • http://www.flintandtinder.co.uk Adam

    Ok, I’ve managed to get a text field with the ID vd_homepage_text to display using this code:
    <?php if (get_option(‘vd_homepage_text’)) { echo get_option(‘vd_homepage_text’); }?>
    Is this correct? If so will I have to add the if statement every time I wish to use any of the option panel data? Finally, I also entered line breaks into the text I put in the vd_homepage_text field but this weren’t rendered on the final page. Is there a way I can get WP to pick up on the formatting and include it along with the text?

  • http://daystock.ru финансы,новости,бизнес,аналитика,магазин,деньги,брокер,акции,инвестиции,ценные бумаги,индексы,дивиденды,акционер,энергетика,global,баланс,ф
  • http://www.flintandtinder.co.uk Adam

    Does anyone know why when I try and add shortcode into a field such as [contact-form-7 id="90" title="Contact form 1"] get trimmed to [contact-form-7 id= ?

    Is there anything I can do to stop it?

  • http://triskelwebdesign.com Caio

    I loved this tut, congrats!

  • eventure

    Very pleased to see this article, I have a question to ask, thanks:
    ……

    $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”);

    ……

    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”),

    ……

    <label for="”>

    <select name="” id=”">

    <option >

    ———————

    I really want to know where in the options category name is displayed, and the output is the classification of ID, what code should be changed, thanks (I think: ).

    Thanks.

  • nitin niraj

    sir can u tell me how to add an option in the menu bar of the admin panel wordpress.
    I want an option in the admin panel’s menu bar

  • kutailang

    sir…can you tell me how to upload a file,I want upload the logo,Not fill the url in text form…

    please forgive my foor English…

    thanks

  • Jen

    Anyone wondering how to implement the CUSTOM CSS code, I am using the following successfully:

    <?php if (get_option(‘ppp_custom_css’) ) { ?>
    <!– CUSTOM CSS –>
    <style type=”text/css”>
    <?php echo stripslashes(get_option(‘ppp_custom_css’)); ?>
    </style>
    <?php } ?>

    • http://expertpixels.com/ Expert Pixels

      I must say a big thanks for this tutorial firstly, and a huge thanks JEN for the tip, I was struggling to make the custom css function work.. If anyone is interested in collaberating with me to create a updated theme options tutorial please contact me via my website Expertpixels.com (at the time of writing this Expert Pixels is still being developed, but i am devoted to this project and would love some experts / help to create a much moer in-depth guide of what can be done with wordpress admin options / theme options).

      Regards, Darren

  • http://www.shapingshapes.com Studio Shapes

    Ok. Thanks for the tut. Great post

  • http://tumaykilinc.com Tümay Kılınç

    Thanks, it is easy to follow. I will try it out soon.

  • lynn

    Awesome stuff! Can we use this in a premium theme to sell on theme forest?

    • http://aliogul.com ali

      the same question.

    • ahmetok

      same question, reply plase?

  • Sohail Ahmad

    No Doubt this is an awesome tutorial. Thanks you very much. :)

  • Itachi

    Hi,
    does someone knows how to create a clasic upload button? I want to upload images with uploder, not write manually url path thanks.

    • Jordan

      Try the submit_button(); function

  • xander

    Hi there,

    I noticed that you do not use the nonce.
    There is a rule that says: Do not trust anybody, not even yourselve.
    Why is it that you do not use the nonce when changing settings in the backend?

    Best regards,

    Xander

  • http://wp-fa.com amin

    In the name of God,Firstly i want to say it’s great tutorials,in the following i want to mention that it seems it doesn’t work in wp 3.3. while using this code it got an error link below::
    Notice: Undefined index: page in C:\xampp\htdocs\wordpress\wp-content\themes00\theme_options.php on line 173
    could you help me to fix it?

  • Jakub Kohout

    Hi,
    I have problem with colorpicker. I install your option panel and works fine, but i don’t know how to put colorpicker value to style.php. When I tried this so it display error

    Call to undefined function get_option() in C:\xampp\htdocs\wordpress_vectory2.0\wp-content\themes\vectoryl\css\style.php on line 5

    Do you know hot to fix it?

    thx.

  • helgi

    is it possible to download the files??

  • http://themeforest.net/user/mabuc mabuc

    for those who are asking an upload option.

    array( “name” => “Sample”,
    “desc” => “Enter your sample”,
    “id” => $shortname.”_sample”,
    “type” => “upload”,
    “std” => “”),

    case ‘upload’:
    ?>

    <label for="”>
    <input name="” id=”" type=”text” value=”" />

    <?php
    break;

    function my_admin_scripts() {
    if(is_admin()) {
    $file_dir = get_bloginfo('template_directory');
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
    wp_register_script('my-upload', $file_dir."/includes/mabuc-panel/my-script.js", array('jquery','media-upload','thickbox'));
    wp_enqueue_script('my-upload');
    }
    }

    function my_admin_styles() {
    if(is_admin()) {
    wp_enqueue_style('thickbox');
    }
    }
    add_action('admin_print_scripts', 'my_admin_scripts');
    add_action('admin_print_styles', 'my_admin_styles');

    jquery:

    jQuery(document).ready(function() {

    jQuery(‘#upload_image_button’).click(function() {
    formfield = jQuery(‘#bt_sample’).attr(‘name’);
    tb_show(”, ‘media-upload.php?type=image&TB_iframe=true’);
    return false;
    });

    window.send_to_editor = function(html) {
    imgurl = jQuery(‘img’,html).attr(‘src’);
    jQuery(‘#bt_sample’).val(imgurl);
    tb_remove();
    }

    });

    I hope this helps…

  • http://themeforest.net/user/mabuc Mabuc

    for those who are asking an upload option. (clearer version)

    array( “name” => “Sample”,
    “desc” => “Enter your sample”,
    “id” => $shortname.”_sample”,
    “type” => “upload”,
    “std” => “”),

    case ‘upload’:
    ?>

    <label for="”>
    <input name="” id=”" type=”text” value=”" style=”width:222px;” />

    <?php
    break;

    function my_admin_scripts() {
    if(is_admin()) {
    $file_dir = get_bloginfo('template_directory');
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
    wp_register_script('my-upload', $file_dir."/includes/mabuc-panel/my-script.js", array('jquery','media-upload','thickbox'));
    wp_enqueue_script('my-upload');
    }
    }

    function my_admin_styles() {
    if(is_admin()) {
    wp_enqueue_style('thickbox');
    }
    }
    add_action('admin_print_scripts', 'my_admin_scripts');
    add_action('admin_print_styles', 'my_admin_styles');

    //JQUERY

    jQuery(document).ready(function() {

    jQuery('#upload_image_button').click(function() {
    formfield = jQuery('#bt_sample').attr('name');
    tb_show('', 'media-upload.php?type=image&TB_iframe=true');
    return false;
    });

    window.send_to_editor = function(html) {
    imgurl = jQuery('img',html).attr('src');
    jQuery('#bt_sample').val(imgurl);
    tb_remove();
    }

    });

    sorry for the double post..

    thanks,
    mark

    • http://google-plus-info.blogspot.com/ G+ Info

      it’s not working on me :(

    • Charles

      Mark, how do I properly implement the code you have provided? I’d love to allow my users the option of uploading content, but I haven’t been able to get this working properly. Thanks in advance for your help.

    • http://ageprumanto.com Agep Rumanto

      For working properly, match the jguery id with input id (in the form). for example in this case, you can change input id to “upload_image_button”, and then change the jquery(‘#bt_sample’) to the text field destination. for example you want send the url of the uploaded image to “nt_logo”.. that’s it.

    • Mabuc

      Guys, check my updated code above.. it works fine in 3.5

    • phil

      hello, can you please explain it more.. are those code all goes to function.php? and the file my-script.js should it be in a theme directory? i like the idea of uploading media on the panel..

      i would love to see your code working on my theme.. also i am getting problem in case; statement.. am not a programmer guru so any help will appreciate…

      thanks

      • http://twitter.com/eb_p1 Ernest Burnett

        phil, take the download, remove the encryption and re-zip what’s in the ‘Final’ directory – into something like nettuts-tutorial and zip the top level working parts into another directory (delete out the final directory and ds store contents) into another – after you repackage, call up in your WP admin panel via Appearance Themes and load them both in – as you work through the tutorial you can check swap thru both versions of the function.php files/js/css as you build, in case you get stuck with the wording in the tutorial (to get an idea of what you are supposed to be doing, or if there may be any typos)

  • http://gaiarendering.com Dan

    First of all thanks for this great piece of code. I am just getting in this type of customization and found it really useful! I was having trouble getting my google analytic code to display correctly then figured out that I needed to call the option using stripslashes like:

    <?php echo stripslashes(get_option(‘rm_ga_code’)); ?>

    hope this helps another php noob!

  • http://na Samir

    I really love this tutorial, but unfortunately, everytime I am trying to save the values of the options page I am getting a “You do not have sufficient permissions to access this page.”
    This is a multisite, and I am logged in as the Network Admin.
    What am I overlooking ?
    Any help is greatly appreciated.

  • http://learnwebtips.blogspot.com/ Ashkar

    Hi Rohan Mehta,

    This is one of a superb and useful tutorial I have seen ever… Thanks… :)

  • r@J

    This is Awesome tutorial. No doubt about it. It helps a lot. Thank you. GOD bless you.

  • Fabio

    I’m getting the following message when I try to add an option:

    You do not have sufficient permissions to access this page.

    any help? :(

  • http://andor1995.info/ Nagy Andor

    Hey, Great tutorial!

    The color change works perfectly. But I don’t know how to make the custom logo to work.
    I’d like to display the logo if it is set, else the site name and description. is it possible?

    Thanks for the great tutorial again.
    Regards, Andor.

  • http://eddiepotros.com e11world

    This doesn’t seem to be a complete tutorial. Some options don’t seem to work (such as the colors) and others are not even visible in the functions.php (or maybe I can’t see it anywhere). It is a good attempt and a nice way to open the doors for more options.

  • JW

    Hey,

    Thanks for a great tut. What I’m wondering is, I’d like to create a set of three columns on the homepage of my site, the text of which users can edit from the options panel along with a place to upload an image for the column. I’ve already got the text and title display on the homepage as well as an anchored button.

    What I’d like to know is, I’d like to be able to display the options to edit these three columns in a table format, however without using HTML tables. What I want to know is, how do I go about editing the code in this tut to then allow me to style the editing panels that way.

    Also, how could I edit this code to make tabbed navigation? Rather new to WordPress development, and I’m really working super hard at learning all of the ins and outs.

    Thanks!

    JW

  • http://www.studio88design.com Rob

    This is a fantastic post – period…..

    I’m working on my first theme and it’s amazing how the frontend design is only a minor part of the whole theme development process. It’s the backend stuff that’s difficult to understand, and this post brought things into perspective.

    Thanks.

  • Bowlodesigns

    To the author can I use this to create a premium them and sell it. In other words can i use it for any purpose.

  • http://none michel

    Hi,
    Please help me,
    How do I show the default values stored in ‘std’ if user has not given any input.
    and another thing, I have added this admin panel in to my theme, but when I first activate the theme, it does not shows the default values by it self, in order to display the default values I have to hit the save changes button first.
    so please help,
    thanks.

  • http://furqankhanzada.com Furqan Khanzada

    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”),

    this code output is

    Choose a category
    Free Stuff
    Good Ideas

    But i want with value with cat id. like

    Choose a category
    Free Stuff
    Good Ideas

    because

    query_posts(‘category_name=’.$cat_name.’&posts_per_page=10′);

    in this case is not working properly. that’sway i need cat id then i can use id. like

    query_posts(‘cat=’.$cat_id.’&posts_per_page=10′);

    also tell me how can i call id in loop page.

    Thanks in Advance :)

    • http://furqankhanzada.com Furqan

      however html code is not print in above question i think you can understand what am i asking …

  • David geckocode

    Hi everbody! I have a tricky question:

    I have a custom theme options panel with many textareas for custom info. All those text fields are duplicated for versions in different languages, english and spanish. I use to work with qtranslate for switching languages.

    As i want to optimize my php code, i though about the posibility of using the current language in a variable to choose the corresponding info, width the same value on its ID.
    I better explain with an example:

    I have the following ID for two descaription fields:
    id(english) = nt_description_en_US
    id(spanish) = nt_description_es_ES

    Then in my template:

    $blog_lang = get_bloginfo(‘language’);// Here i get the language, so if my qtranslate is in Spanish this variable return “es_ES”

    $var1 = get_option(‘nt_descripcion-1_’.$blog_lang);// Here i try to put dynamically the languange in the variable id. What i expect to retrieve is “nt_descripcion-1_es_ES”

    Don´t print anything!!

    I have read that isn’t possible to print variables as get_option attributes. Is there a way to get it??
    Sorry for my horrible english, i hope someone can help me. Thanks!

  • Sagar

    Hi, Nice tutorial, but when i make the changes in the settings panel, it wont show up in the front end(website). Why?

  • Dougal Graham

    Did you copy this from aquoid, or them from you? It’s basically identical:

    http://aquoid.com/news/tutorials/wordpress-theme-options/w-theme-options-setting-and-retrieving/

  • http://www.superdesigngirl.com Katherine

    This was a great tutorial! Thank you so much! great job! have your written any other tutorials?

  • Lauren

    Worked well but stopped displaying the “Theme PANEL” after WP upgrade to 3.4 :(
    Any idea why?

    Maybe the code should be updated with Theme customization API?
    http://codex.wordpress.org/Plugin_API/Action_Reference/customize_register

  • Lauren

    Fixed!

    Instead ‘administrator’ (part 5, line 30) I had written ‘edit_themes” and that hidded the ‘Theme panel’ link (?)

    Finally, I switched to ‘edit_theme_options’ and it works as well the core code.

    Great tutorial :)

  • http://blog-university.com sandeep

    great job rohan

  • test

    great work!!!!!!! but this tutorial does nt work as it doesnt save the settings options

  • Lucien Dubois

    Hi, I try to create an array so the user could check abox to enable/disable a dashboard widget.
    I tried to create an array (which I see in the panel)

    array( “name” => “Extensions dashboard widget”,
    “desc” => “Enable/disable Extensions dashboard widget”,
    “id” => $shortname.”_admin_ext”,
    “type” => “checkbox”,
    “std” => “”),

    and then I wrote the following (see http://www.wprecipes.com/how-to-programatically-remove-wordpress-dashboard-widgets)

    function remove_dashboard_widgets() {
    global $wp_meta_boxes;

    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins']);
    }

    if (!current_user_can(‘manage_options’) &&(function_exists(‘ek_admin_ext’))) {

    }
    add_action(‘wp_dashboard_setup’, ‘remove_dashboard_widgets’ );

    and also this

    function remove_dashboard_widgets() {
    global $wp_meta_boxes;

    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_plugins']);

    if (!current_user_can(‘manage_options’) &&(function_exists(‘ek_admin_ext’))) {

    }
    }
    add_action(‘wp_dashboard_setup’, ‘remove_dashboard_widgets’ );

    But I still get that message: ou do not have sufficient privileges to access this page.
    What is wrong? I don’t really know how to get the option check or not checked.
    What code should I try?

  • http://interversant.com Brian Myrick

    Used this as the basis for a theme option I’m working on. Thank you.

    I’m having one problem with it however. Whenever I save or reset, I get the white screen of death. The only error in the log is “HP Warning: Cannot modify header information – headers already sent by (my php file:152) in …/wp-includes/option.php

    I thought the problem might be these:

    header(“Location: admin.php?page=panelbackground.php&saved=true”);

    But even commented out, the same issue occurs. Anyone have any ideas?

    Thanks

  • Selmat

    Great post.

    Guys, can anyone help me to create a submenu and sub page to this panel ?

    I am struggling but noway.Please help me.

  • Jeremen

    <textarea name="” type=”" cols=”" rows=”">

    The textarea tag doesn’t have type attribute and thx for tutorial.

  • Mabuc

    this is what I used in WP3.5
    add this code in your “upload.js” file..

    jQuery(document).ready(function() {

    /****************************
    JQUERY UPLOADS
    ****************************/

    var formfield = '';
    var formfield_video = '';
    var formfield_audio = '';
    jQuery('#upload_image_button_background').click(function() {
    formfield = jQuery('#background').attr('name');
    tb_show('', 'media-upload.php?type=image&TB_iframe=true'); //change the type you want (image, video or audio)
    return false;
    });

    /****************************
    SEND EDITOR
    ****************************/

    var original_send_to_editor = window.send_to_editor;
    window.send_to_editor = function(html) {

    /*IMAGE :: VIDEO :: AUDIO*/

    if(formfield) {
    fileurl = jQuery(html).attr('src');
    if (typeof(fileurl)==="undefined") {
    fileurl = jQuery('img',html).attr('src');
    }

    jQuery('#' + formfield).val(fileurl);
    tb_remove();
    formfield = '';
    }else if(formfield_video) {
    fileurl_video = jQuery(html).attr('href');
    if (typeof(fileurl_video)==="undefined") {
    fileurl_video = jQuery('video',html).attr('src');
    }

    jQuery('#' + formfield_video).val(fileurl_video);
    tb_remove();
    formfield_video = '';
    }else if(formfield_audio) {
    fileurl_audio = jQuery(html).attr('href');
    if (typeof(fileurl_audio)==="undefined") {
    fileurl_audio = jQuery('audio',html).attr('src');
    }

    jQuery('#' + formfield_audio).val(fileurl_audio);
    tb_remove();
    formfield_audio = '';
    }else {
    original_send_to_editor(html);
    }
    };
    });

  • dannyrobes

    @0e5572992910c626087e5f820d138e47:disqus I am having trouble getting that code to work. Could you zip up a demo of this functionality added to this tutorial’s theme?

  • pinghole1

    Great tut, been using it for a long time and works great. I came across one issue that has boggled my mind and wondering if you have any insight into the issue.

    http://wordpress.stackexchange.com/questions/80458/wp-custom-theme-admin-menu-data-being-erased-by-wp-custom-background-upload-butt

    Basically when i turned on custom-background support in my functions.php page the page show up and works all except when i try to upload an image on the Background page in wp-admin. When i select an image and then hit the Upload button, it re-directs me to my custom theme settings page with all of my data that i had saved now gone and the saved settings success message showing.

    Any insight into this would be awesome.

  • http://www.kellerclub.eu Robert

    Hi, thanks for the great tutorial. I’m working on my first theme and building the options page was pretty easy with your tutorial.
    But I have a problem (?): When I “save” changes, those changes aren’t shown in the forms. Is there a way to use the current (basically: last saved) values in the input-fields?

  • Ahmed

    Hey Guys, i have done all that and all is good ,but i have just one question:how can i use that like rss link how can i place it on my blog.{sorry for bad english iam arabian :) }