WordPress Theme Options: A Guide


These days with so many WordPress themes being released, you need something to make your theme stand out from the crowd. One of the ways you can do this is by creating an awesome theme options page. In this post we’ll explore exactly how to do that. And at this point, it’s worth saying the code used in the next two tutorials has been taken from a couple of themes – the Arras theme and the miniBlog theme (although be wary using it – sponsored links in the footer!).

Update 21.08.09: this tutorial series has been updated with a new series – check out “Create An Advanced Theme Options Page in WordPress“.

What we'll be creating. Good isn't it!

Getting started

Right. Lets get to it. First thing, create new file, functions.php. Save it and upload it to your theme folder. Next, lets start the admin page. My hypothetical theme I’m using in this tutorial is called ‘Hexadecimal’, or hd for short:

<?php // Theme options page
  1. // Created using the tut at WPShout –> http://wpshout.com/create-an-awesome-wordpress-theme-options-page-part-1/
  2. $themename = "hexadecimal";
  3. $shortname = "hd";
  4. $options = array (

Copy and paste the code above into your functions.php file, replacing the themename with your theme’s name and shortname with a shortened version of your theme’s name.

The options:

Allow the user to change the theme’s colours

So now we’ve started, next thing we need to is start creating the options. But before we do that, let’s say hello.:

  1. "name" => "Hello.<br /> Isn't this fun!",
  2. "type" => "misc"),

And there we are. We’ve just siaid hello. Now lets start doing some useful stuff! Something that is pretty awesome is being able let your theme’s users customise the colours of the theme from the options page. This is where it could start getting complicated, so just bear with me!

Selecting colours is going to have two options, so first thing to do is to make a title:

array(  “name” => “Select Your Colors”,  “type” => “title”),
  2. array( "type" => "open"),

Next, we’re going to add the option to change the background image. First, a little explanation: ‘name’ is the title. ‘desc’ is a little description of what the option does. ‘id’ is what’ll we’ll use in part two to implement the colour changing into the theme in part two. ‘std’ is what is displayed by default and ‘image’ is the little explanatory image that gets displayed below the title (which we’ll implement later).

I digress. Copy, paste and customise the code below.

  1. "name" => "The Background (colour)",
  2. "desc" => "Here you can choose the background colour for the whole site. Awesome, no?  In other news, you'll need to put the colour in #000000 format, except without the # bit.",
  3. "id" => $shortname."_main_bg",
  4. "std" => "000000", "type" =>
  5. "text", "image" =>  "background.jpg"),

Next, lets create another option, allowing the user to customise the page colour:

  1. "name" => "Another Colour",
  2. "desc" => "This is another colour used somewhere else in the theme. Again, #000000 just without the # bit.",
  3. "id" => $shortname."_another_bg",
  4. "std" => "ffffff",
  5. "type" => "text",
  6. "image" => "anothercolour.jpg"),

Now that we’ve given the user some coluor changing options, we need to close that section.

"type" => "close"),

array( "type" => "submit"),

Give the user some enable/disable options

Now we've created the first bit, that's the hard bit out of the way. The rest of the way is plain sailing, just giving a couple more options. Lets say we want to give the user the option to enable/disable the search bar. The only extra thing we need now is a checkbox, which is set by default to 'true':

(or course, first we're popping in a title)

  1. array(
  2. "name" => "Add/remove stuff",
  3. "type" => "title"),
  5. array(   "type" => "open"),
  7. array(  "name" => "Display the search box?",
  8. "desc" => "Tick/untick the box to show/disable the search box.",
  9. "id" => $shortname."_search_box",
  10. "type" => "checkbox",
  11. "image" => "searchbox.jpg",
  12. "std" => "true"),

(and, of course, closing off the section)

  1. array(
  2. "type" => "close"),
  4. array(  "type" => "submit"),

The possibilities for a simple checkbox are endless - you can be showing/disabling elements everywhere on your theme! As with the colour changing, we'll be implementing this in part two.

Adding a text box

Final option we'll be adding in is a simple text box. It sounds simple, but the possibilities are almost endless. The example below is the user's name, with the default Frederick.

  1. array(
  2. "name" => "Some text you can customise",
  3. "type" => "title"),
  5. array(  "type" => "open"),
  7. array(
  8. "name" => "What is your name?",
  9. "desc" => "Names are an integral part of our society. My name is Frederick. What's yours?",
  10. "id" => $shortname."_my_name",
  11. "type" => "text", "image" => "",   "std" => "Frederick"),
  13. array(  "type" => "close"),
  15. array( "type" => "submit"),

(if this is the last option, then replace the last four lines with:

  1. array(  "type" => "close")  );


Creating and styling the options page

So now we've created our options, we need to style them. This is where everything comes together - all the little bits we've been adding in - now we're going to make use of them. Before we do that though, we need to tell WordPress to add the options page:

(see download below)

Next comes the styling bit. For each of the 'type's we created earlier, we need some styling. For example, the first thing we did was say hello, with the 'type' misc, so lets create styling for all types labelled misc:

(this must go directly below the code above, and includes some stuff you'll need even if you don't use a type misc)

(again, see downlad below).

Next, we need some styling for the title:

<?php break; case "title": ?>
  1. <div style="width:810px; height:22px; background:#555; padding:9px 20px; overflow:hidden; margin:0px; font-family:Verdana, sans-serif; font-size:18px; font-weight:normal; color:#EEE;">
  2. <?php echo $value['name']; ?> </div>

The next thing we made was the background colour changer, with the type 'text'. You can guess where this is going -

<?php break;
  1. case 'text':
  2. ?>
  3. <div style="width:808px; padding:0px 0px 10px; margin:0px 0px 10px; border-bottom:1px solid #ddd; overflow:hidden;">
  4. <span style="font-family:Arial, sans-serif; font-size:16px; font-weight:bold; color:#444; display:block; padding:5px 0px;">
  5. <?php echo $value['name']; ?>
  6. </span> <?php if ($value['image'] != "") {?>
  7. <div style="width:808px; padding:10px 0px; overflow:hidden;">
  8. <img style="padding:5px; background:#FFF; border:1px solid #ddd;" src="<?php bloginfo('template_url');?>/images/<?php echo $value['image'];?>" alt="image" />
  9. </div>
  10. <?php } ?>
  12. <input style="width:200px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "")
  13. { echo stripslashes(get_settings( $value['id'] )); } else { echo stripslashes($value['std']); } ?>" />
  15. <br/>
  17. <span style="font-family:Arial, sans-serif; font-size:11px; font-weight:bold; color:#444; display:block; padding:5px 0px;">
  19. <?php echo $value['desc']; ?>
  20. </span>
  21. </div>

Next up was the checkbox -

  1. break;
  2. case "checkbox": ?>
  3. <div style="width:808px; padding:0px 0px 10px; margin:0px 0px 10px; border-bottom:1px solid #ddd; overflow:hidden;">
  4. <span style="font-family:Arial, sans-serif; font-size:16px; font-weight:bold; color:#444; display:block; padding:5px 0px;">
  5. <?php echo $value['name']; ?>
  6. </span>
  8. <?php if ($value['image'] != "") {?>
  9. <div style="width:808px; padding:10px 0px; overflow:hidden;">
  10. <img style="padding:5px; background:#FFF; border:1px solid #ddd;" src="<?php bloginfo('template_url');?>/images/<?php echo $value['image'];?>" alt="image" />
  11. </div>
  12. <?php } ?>
  13. <?php if(get_option($value['id'])){ $checked = "checked=\"checked\""; }else{ $checked = "";} ?>
  14. <input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> />
  16. <br/>
  18. <span style="font-family:Arial, sans-serif; font-size:11px; font-weight:bold; color:#444; display:block; padding:5px 0px;">
  20. <?php echo $value['desc']; ?>
  22. </span>
  24. </div>

Finally we had a textbox - although that had the type text, which we've already created the option for. All that is left to do is add some code that adds 'submit' styling and closes everything off.

  1. break;
  2. case "submit": ?>
  3. <p class="submit">
  4. <input name="save" type="submit" value="Save changes" />
  5. <input type="hidden" name="action" value="save" />
  6. </p>
  8. <?php break; } } ?>
  9. <p class="submit">
  10. <input name="save" type="submit" value="Save changes" />
  11. <input type="hidden" name="action" value="save" />
  12. </p>
  13. </form>
  15. <form method="post">
  16. <p class="submit">
  17. <input name="reset" type="submit" value="Reset" />
  18. <input type="hidden" name="action" value="reset" />
  19. </p>
  20. </form>
  22. <?php
  23. }
  25. add_action('admin_menu', 'mytheme_add_admin');
  27. ?>

And finally

And there we go! All that is left to do is add in some images, which we've called searchbox.jpg, background.jpg and anothercolour.jpg. Create them and upload them to /yourtheme/images/.

You can download the functions.php file that follows the tut here

So that's the options page created. In the next part of the series, we'll be implementing the features we've created into a theme. Subscribe to the RSS feed so that you don't miss it!

Found this helpful? You'll find us helpful!

WPShout is published by a full-service WordPress-loving constultancy, Press Up. Get in touch with us about your project or business idea, we're knowledgable and friendly.

About the author

Hello, I'm Alex! I started WPShout in 2009, just before my 16th birthday. Get in touch with me, I'd love to chat. You should also follow me on Twitter :)


  • Mike Brisk

    Thanks for laying that out, I saw that in the miniblog theme and was wondering how that was done.

  • Thanks for this! Very helpful.

  • Thanks for the easy tutorial.
    Quick question. Where are the values that a theme user enters stored?

    I ask because if I release a theme update (new functions.php file) that is installed by the user, will they have to reinput all the options or will they be retained?

    • Alex Denning

      I they’re stored in the database, but you’ll want to confirm that.

      • Hello,

        I’m creating a theme for themeforest, and I’m using a css stylesheet using php and php variables. (http://net.tutsplus.com/tutorials/php/supercharge-your-css-with-php-under-the-hood/)

        I’d like to be able to define variables in that style.php file through the theme options page. Is that possible?
        Basically, I don’t want to switch between different css files, but I just want to change the value of 1 php variable and have it register and apply in the style.php file.

        Please let me know here, or preferably via e-mail if you know

        PS: Superb tutorial!

        • Alex Denning

          I don’t think it’d be appropriate for me to reply to your question either here or by email. I don’t recall seeing any comments from you before on the site and just coming here and looking for help for a template you’re going to sell just isn’t on. I’ll happily answer questions from readers, but I’m not going to make a vital part of your template for you or anyone.

          • I’m very sorry if I offended you. I just found this article and your site because of my problem, which is why I haven’t commented anywhere else. I just wanted to know if it was possible to declare php variables in the options page. I wasn’t asking for you to do it.
            Sorry for the confusion,


  • WOW! Thank you for this amzing tutorial..I now understand how to add different functions and style them.

  • I can't wait to give this a try. I'm going to bookmark your site because it looks like you're giving valuable information.

  • Henrique

    Nice tutorial, thanks!
    Just to let you know, the download link for the functions.php file is broken.

  • The download link for the FUNCTIONS.PHP is broken… the link says “functions.txt” and you get an error 404 message.
    .-= Mike Fulton´s last blog ..Revisiting GEM For The Atari ST, Part 1 =-.

    • Alex Denning

      Oops. I did update, but the database reverted to a version a couple of days old and it looks like it’s been lost. Post updated.

  • I got it now :)

  • thanks for this wonderful tutorial!!
    .-= Akshay´s last blog ..Ultimate Youtube Grabber Script v2.0 =-.

  • Hi Alex,

    first let me say thank you for a great series of tutorials on theme options pages.

    I was wondering if a theme options page needs to have a nonce field in it for security or if this only applies for plugins?

    If this is the case, would you then just use the wp_nonce_field(‘my-nonce’); right after the opening form tag or would you add a nonce field for each form element, using the elements name?

    I thank you for your time.


    • Alex Denning

      Hey Olaf. You’ll want to first check out the series I’m running this week creating an advanced theme option page. Links on the homepage.

      If I’m honest, I don’t know. The only thing I can suggest is try it out and see where it gets you. Do let me know how you get on :)

      • Hi Alex,

        I will have a look at your series, looking forward to learn something new.

        Ok, I will try and post a question on the wordpress forum and see if anybody there has some insight into this. As soon as I know anything regarding Nonce in the Theme Options page, I will post a comment with my findings here.

        .-= Olaf´s last blog ..WPreso Video Flow v0.3 released =-.

  • Great tutorial, working through it right now. Glad to see straight forward explanations.
    .-= Matt Propst´s last blog ..The easy way to grow traffic to your site =-.

  • Keith

    Thank you for this tutorial. GReat information

  • lusman

    Hi Alex,

    I really enjoy your tut.

    But I have some questions about image (like background.jpg, searchbox.jpg, anothercolour.jpg) . I can’t figure how about them. Can you give me images in this tut?



  • lusman

    Oh, sorry about that. I have them now!

    Thank again ’cause this interesting tut!