How To Create An Options Page For Your WordPress Theme

WordPress is one of the most popular Content Management Systems. Also WordPress is 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 when making themes. Additionally, themes buyers find the options panel too easy to use rather than having to open up the PHP template files and fiddling with the code.

Today we will be incorporating an options panel for the WordPress Classic theme. The methods you will learn will allow you to very easily integrate it into an existing theme you’re working on.

Setting The Files :

The theme that we will be working on is the classic theme provided by wordpress. You can find it on wp-content/themes folder. You should see the following files:

  • index.php
  • functions.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 will be done within the functions.php file.

Now go to your wordpress admin panel then go to Appearance>Themes  and activate the classic theme.

Working on functions.php :

Begin by opening up functions.php in your code editor of the classic theme ( wp-content/themes/classic/functions.php ) then insert the following code :

<?php
$themename = "Classic Theme";
$shortname = "ct";

I added two variables the first one reffers to the name of the theme and the second is the shortname : You can choose any name for these two variables but don’t forget to select significant names because you will be using them later.

Now let’s start adding some options for our theme :

$options = array (
    array( "name" => $themename." Options",
           "type" => "title"),
    array( "type" => "open"),
    array( "name" => "Color Scheme",
           "desc" => "Select the color 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" => "Homepage header image",
           "desc" => "Enter the link to an image used for the homepage header.",
           "id" => $shortname."_header_img",
           "type" => "text",
           "std" => ""),
    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" => "Paste your Google Analytics or other tracking code in this box.",
           "id" => $shortname."_ga_code",
           "type" => "textarea",
           "std" => ""),
    array( "name" => "Feedburner URL",
           "desc" => "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"));

Here the variable “option” contains a big array which also contains other child arrays. Each child array holds an option.

The first array reffers to the title of the page ( In our case it’s ‘Classic Theme Options’ ). Every time when we want to add a new option we have to declare an array with a type and give it the name we want.

You can take a look at 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.

Now we have our options ready but how can we view them ? 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: themes.php?page=functions.php&saved=true");
die;
} else if( 'reset' == $_REQUEST['action'] ) {
foreach ($options as $value) {
delete_option( $value['id'] ); }
header("Location: themes.php?page=functions.php&reset=true");
die;
}
}
add_menu_page($themename." Options", "".$themename." Options", 'edit_themes', basename(__FILE__), 'mytheme_admin');
}

Here I declared a function with a name of “mytheme_add_admin”. This function is used for updating options : If the options are saved, 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 theme page( add_theme_page ) in Appearance box and it calls mytheme_admin function. If you want you can replace add_theme_page with add_menu_page to create an external box :

At this step we still don’t have the theme options page, so we have to write mytheme_admin function which was called by add_theme_page, add this code to functions.php :

function mytheme_admin() {
global $themename, $shortname, $options;
if ( $_REQUEST['saved'] ) echo '<div id="message"><p><strong>'.$themename.' settings saved.</strong></p></div>';
if ( $_REQUEST['reset'] ) echo '<div id="message"><p><strong>'.$themename.' settings reset.</strong></p></div>';
?>

Here we have some conditions : if the settings are saved WordPress will show ” Classic theme settings saved “. Likewise for reset.

Now paste the code above I will explain it after :

<div class="wrap">
<h2><?php echo $themename; ?> Settings</h2>

<form method="post">

<?php foreach ($options as $value) {
switch ( $value['type'] ) {

case "open":
?>
<table width="100%" border="0" style="background-color:#cdcdcd; padding:10px;">

<?php break;

case "close":
?>

</table><br />

<?php break;

case "title":
?>
<table width="100%" border="0" style="background-color:#868686; padding:5px 10px;"><tr>
<td colspan="2"><h3 style="font-family:Georgia,'Times New Roman',Times,serif;"><?php echo $value['name']; ?></h3></td>
</tr>

<?php break;

case 'text':
?>

<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><input style="width:400px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?>" /></td>
</tr>

<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr>

<?php
break;

case 'textarea':
?>

<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><textarea name="<?php echo $value['id']; ?>" style="width:400px; height:200px;" type="<?php echo $value['type']; ?>" cols="" rows=""><?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?></textarea></td>

</tr>

<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr>

<?php
break;

case 'select':
?>
<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>"><?php foreach ($value['options'] as $option) { ?><option<?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option><?php } ?></select></td>
</tr>

<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr>

<?php
break;

case "checkbox":
?>
<tr>
<td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
<td width="80%"><?php if(get_option($value['id'])){ $checked = "checked=\"checked\""; }else{ $checked = "";} ?>
<input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> />
</td>
</tr>

<tr>
<td><small><?php echo $value['desc']; ?></small></td>
</tr><tr><td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td></tr><tr><td colspan="2">&nbsp;</td></tr>

<?php break;

}
}
?>

<p class="submit">
<input name="save" type="submit" value="Save changes" />
<input type="hidden" name="action" value="save" />
</p>
</form>
<form method="post">
<p class="submit">
<input name="reset" type="submit" value="Reset" />
<input type="hidden" name="action" value="reset" />
</p>
</form>
</div>

Explanation :

With this code we created our options page content : I used a php foreach loop, each option type is evaluated on a case-by-case basis. So if the type of the option is title do this, if it is a checkbox do that…

If there is an “open” type option we do nothing. If there is a “close” type options, we close our table. For each of the types “text” , “select” , “checkbox” and “textarea” , we display the corresponding input. At the end we added two buttons one to save the settings and the other to reset them.

Now our options page is ready, but we have to add this short code to make it work :

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

This short code tells WordPress to add the admin menu.

After all this, here the result you should end up with :

In this example I used simple styles included in functions.php to make our options page looks better but I will show you how to add a stylesheet to functions.php so you can add your styles rapidly.

How to add a stylesheet to functions.php :

First, you have to create a new folder on your theme folder, name it functions then create a new css file with a name of functions.css. After flling your css file add this code to functions.php after mytheme_add_admin function :

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

Also, if you want you can use scripts to make your options page better by including a js file.To do this you have to change

wp_enqueue_style("functions", $file_dir."/functions/functions.css", false, "1.0", "all");

To :

wp_enqueue_script("script", $file_dir."/functions/script.js", false, "1.0");

After adding your stylesheet or your script, you have to add this code under add_action(‘admin_menu’, ‘mytheme_add_admin’); so they will be active :

add_action('admin_init', 'mytheme_add_init');

Making Use of the Options :

Now after creating our options, I will show you how to make use of them. First up, open up your header.php file, and add the following code:

<?php
global $options;
foreach ($options as $value) {
    if (get_settings( $value['id'] ) === FALSE) { $$value['id'] = $value['std']; } else { $$value['id'] = get_settings( $value['id'] ); }
}
?>

You must put the code above at the start of all the files which you add options to. Once you’ve done that you can begin using your options. For example : If you want to display the footer text you have to echo $ct_footer_text ( ct reffers to the shortname of the theme ) :

<?php
echo $ct_footer_text;
?>

For a checkbox you can check if the box is checked ( it will return true ) do this…

You can download the functions.php file here.

That’s it ! Thanks for reading this tutorial and I hope it was useful.

1STWD Editorial

15 Smart Tools To Help You Build Your Freelance Business

Discover the awesome tools we use in making our clients comfortable and happy in learning new things every day.

Download Now

Comments

  1. Glen says

    hi there, I’m trying to use Textarea for Google Analytics code option. But why the result changing the code?
    From:

    ar _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-29509388-1']);
    _gaq.push(['_trackPageview']);

    (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();

    to

    var _gaq = _gaq || [];
    _gaq.push([\'_setAccount\', \'UA-29509388-1\']);
    _gaq.push([\'_trackPageview\']);

    (function() {
    var ga = document.createElement(\’script\’); ga.type = \’text/javascript\'; ga.async = true;
    ga.src = (\’https:\’ == document.location.protocol ? \’https://ssl\’ : \’http://www\’) + \’.google-analytics.com/ga.js\';
    var s = document.getElementsByTagName(\’script\’)[0]; s.parentNode.insertBefore(ga, s);
    })();

    • Ariful H Bhuiyan says

      Hi.. I am having the same problem as G+ Info.. When I put Google Analytics script, it add some in many places. how to solve this please?

  2. Mike Mackintosh says

    just stumbled upon this taking a stab at wp themes. this is a great point of reference for a wp theme/widget noob.

    Thanks!!!!

  3. Joseph says

    how to have the textarea boxes save the paragraphs and line breaks? right now I get one long line of text.

    Thanks for any help

  4. Joseph says

    Very simplified and easy to understand tutorial thank you very much.
    On point, when saving the textarea doesn’t save the line breaks, how can I fix this.

  5. Octavian Ristea says

    Just like Chris said I would also like to know about how to do those color options. THX

  6. Ljubisa says

    You haven’t mentioned where to paste “options page content”.
    “Now paste the code above I will explain it after :”

  7. Roman says

    Really nice tutorial. It was easy to understand how to make options page in WP.
    Thank you!

  8. Chris Raymond says

    I see a lot of premium themes now enable you to select from an array of background color AND texture options.

    Does anyone know what php to use to create that set of options? I’ve looked at some of these themes’ css files and they list a whole bunch of different classes for the background textures, so I am assuming a custom options panel somehow creates an array and then takes the value the user selected and generates that class name in the markup, but I would sure like to get specific php code snippets to do that.

    BTW: I am a designer who knows enough about php to be dangerous, so if you know how to do the above, please keep in mind to simplify your explanation for the non-programmer. TIA!

  9. james carter says

    sorry. I fixed the problem. for some reason i had php that was setting up custom sidebars and menu above your code. I switched it to be below and everything worked. I have much to learn about php. :)

  10. James Carter says

    I have been receiving this error message when clicking the save button. any ideas Warning: Cannot modify header information – headers already sent by? thanks good tutorial.

  11. Alex says

    Thanks for the tip. It really helped me to understand how to make a powerfull options page in wordpress.

    Thanks,
    Alex

  12. Burke says

    Thanks so much. I followed this tutorial a few months back and it worked fine. Now when I save the options, they save, but I get the message on a white next page:

    “You do not have sufficient permissions to access this page.”

    How do I stop this from happening?

    • Joseph says

      I fixed this by editing the two instants of header where it says
      header(“Location: themes.php?page=functions.php&saved=true”);

      to point to you page URL, in my case:
      header(“Location: admin.php?page=admin-options-page.php&saved=true”);

  13. James says

    So much better than other tutorials on how to do this. Yours is more organized and easier the read. Thank you. ^^

  14. James says

    I was trying to follow this tutorial and let me just tell you that yours is far superior. It’s easier to read and understand and much easier/quicker to follow the steps. Had this up and running in like 30 mins. I spend my entire day yesterday trying to figure out that nutjobs tutorial. Thank you, so much.

  15. Naupad says

    The tutorial is good but If I already have a theme options page in the parent theme and want my own customizations in the child theme, how can I create a theme options page for child theme as common functions like mytheme_add_admin would conflict with those in parent theme and raise error….

    Help….

  16. Todd says

    So, when was this blog post written? I can’t see a time stamp anywhere so I don’t know if this is out of date or not.

  17. Noor Mustafa says

    Thanks! I’ve been getting those errors in a couple of little websites. Now I know what the heck is going on and have written on it also

  18. Alexander Theis says

    Hi this is a really nice guide. But i have following problem.
    If I click on Save or Reset i will get an error.
    “Warning: Cannot modify header information – headers already sent by… ”

    Does anybody know something about it? Error is in this line
    “header(“Location: themes.php?page=functions.php&saved=true”);”
    “header(“Location: themes.php?page=functions.php&reset=true”);

  19. says

    Great tutorial.
    Thank you for sharing :)

    @Scott Corgan,
    “header already sent” error is most probable because you have few empty lines in functions.php file

    remove all empty lines from functions.php file and error should be gone.

  20. Scott Corgan says

    Having issues with “header already sent” any ideas?

    Thanks.

    • Sean Thompson says

      Functions.php is very touchy. In PHP you cant have any blank lines. So take out any blank lines and you should be good.

  21. WordPress 101 says

    Great tutorial! Options pages are becoming almost required for anyone who customizes themes, or creates WordPress sites for their clients. Tweeted and shared this with my WordPress 101 members. Thanks again!

  22. says

    Just the thing I wanted! Thank you very much for the share… We can create very complex option pages depending on the theme I guess…

  23. Konstantin says

    I’m sorry, but I don’t like it at all.
    Have you ever heard of WordPress’ Settings API?
    Maybe you want to get familiar with the WordPress Core before you write tutorials that … are no good.

  24. says

    Nice tutorial. I’m definitely going to have to try using these codes and tweaking them to fit my needs. Thanks for posting this up.

  25. says

    HI fri., thanks your training and tutorials. I really got experience for your tutorials. May be you too get a lot of knowledge and share to all other peoples.

  26. Matt @ Theme Thesis says

    Sweeeet. It’s nice to see all these options page tutorials creeping up now. When I first learned how to do them the resources around were so scarce, it was brutal. This is very nicely written, good job!