A Sample WordPress Theme Options Page

Update: This post is crazy old and there are way better options for … options panels now. Like the customizer! Otto can tell you how to leverage the customizer for your theme options. Or, heck, just go ahead and check out the sample code we use all the time.


Problem: You want to create a simple theme options page for your new WordPress theme but all the tutorials and sample theme options pages you’ve seen are way too complex or don’t fit in at all with the existing WordPress look.

Solution: We’ve come up with a simple, sample theme options page you can use for your next theme!

We’ve based this theme options page on the awesome sample plugin options page created by Ozh of Planet Ozh—only now with the bonus Radio and Select options and a Text Area.

Everything is bundled up in a Twenty Ten child theme called A Theme Options Theme—an instant working example—that you can download at the end of this post but here’s how you’d want to use it in your own themes …

How To Use theme-options.php

First, drop theme-options.php in your theme directory and include it in your theme functions.php file like so:

require_once ( get_template_directory() . '/theme-options.php' );

Or, if you’re including the options page with a Child Theme (just like in A Theme Options Theme) like so:

require_once ( get_stylesheet_directory() . '/theme-options.php' );

Then, whenever you need access to one of your new settings, you can do something like the following in any theme template …

<?php
	$options = get_option('sample_theme_options');
	echo $options['sometext'];
?>

Pretty simple, right? While you’re at it, you’ll probably want to use your text editor’s find and replace feature to change “sample” in theme_options.php to the name of your theme. So, for example, if your theme was named Shabadoo you’d go from this …

register_setting( 'theme_options_options', 'theme_options_sample', 'theme_options_validate' );

to something like …

register_setting( 'shabadoo_options', 'shabadoo_theme_options', 'theme_options_validate' );

Of course, Shabadoo is only a suggested theme name. But if you’d like to use it, it’s all yours. Just like theme-options.php is all yours. We hope you can use it to get a quick start on enhancing your themes with a simple options page. Good luck.

Download A Theme Options Theme.

57 responses

  1. Genius! Thank you so much for this. Much better than my few boring text boxes and buttons in a table.

  2. Great. Seems very easy to implement and just what i needed for a next project. Thanks!

  3. Ian, brilliant as always, Sir.

    I can’t help but feel that the only thing ‘missing’ from this excellent little resource is an example about how to deal with file uploads. Plenty of themes allow the end user to upload a logo or other media and I know you can ask the user to upload it into the media library and then copy and paste the url of the file into a text input (as many, many themes do) but having a theme guru such as yourself show us how to ‘properly’ handle file uploads can only be a positive thing for the community.

    I know file uploads are normally a bit of a ‘touchy subject’ but WP has the functions to handle them (and after countless hours googling I did find a solution which I think works well) but I’d love to see something of an ‘official’ way to deal with this.

    On an unrelated note, I’ve seen a few themes (and plugins) that use 2 columns and utilise meta-boxes to hold the different option groups which really makes them look native and after all, familiarity is key!

    Thoughts?

    1. To answer both questions, I prefer simpler theme options. For logo uploading, WordPress already has the Custom Header feature cooked in. And, when it comes to 2-column theme options with metaboxes I like to point to WordPress’ own settings pages. They don’t need multiple metaboxes or multiple columns—and if a theme has more options than WordPress … it has too many options.

  4. Hmm – Would be interesting to see this evolve into a Widgetized theme options (Is that even possible?) — allowing widgets to be added to the options panel. Perhaps offloading some developer work to existing plugins that come in the form of widgets.

    1. I think one of the Google Summer of Code projects for this year has to do with making a more generalized admin widgets framework. Perhaps something will come out of that like what you’re thinking of.

  5. Thank you sir

  6. […] A Sample WordPress Theme Options Page A sample theme options page to easily add some options to your theme without having to digg through tutorials for the basics. (tags: theme wordpress tutorial development options) Leave a Reply Click here to cancel reply. […]

  7. Really nice work sir. This should be helpful for future projects where someone is going to want this.

  8. […] A Sample WordPress Theme Options Page […]

  9. danny Avatar

    This is what I was looking for those last days!

  10. I’ve seen some tutorials about creating an option page for theme, and even looked through the Thematic code and found that all of them use the same techniques. But this code is a bit improved with just one option, that’s quite good. I’ll check it right now. Thanks for sharing.

  11. […] A Sample WordPress Theme Options Page indeed. (tags: wordpress themes design webdev) […]

  12. I added the theme options file and included it in functions.php, but the theme options page does not appear in the admin.
    how can I fix this?

    1. Hi, Paul. Did you use the example above, with require_once()?

      1. will this code only work with WP 3.0?

  13. yes, I added it as the first line of functions.php
    where should the menu appear? under Appearance?
    how can I debug this?

    thanks!

    1. ok, I just installed WP 3.0 RC and it’s working.

  14. […] WordPress – Good Work MS!Improving The WordPress Support ForumGoodbye, headaches. Hello, menus!A Sample WordPress Theme Options PageTechnologyChina aims to become supercomputer superpowerClickjacking Worm Exploits Facebook […]

  15. sorry about all these comments but I have another problem: the value for the dropdown returns to the default value when I click save.
    how can I preserve the selected value?

    1. Hi Paul, email me the code and I’ll take a look at it.

  16. Fantastic! Now I need to see what wicked ideas we all can implement!

  17. a customization guide would be nice.
    I iddn’t manage to get the select to work with categories 😦

  18. To make the select box with WP categories, I just changed the code to:

    $cats = get_categories();
    foreach($cats as $cat){
    $select_options[$cat->term_id]["value"] = $cat->term_id;
    $select_options[$cat->term_id]["label"] = $cat->name;
    }

    1. Excellent. Thanks for the update, Paul.

      1. except it doesn’t work 😀

        but I posted the question on wpquestions.com – hopefully I’ll be able to get this sorted

      2. I used some (similar) code from the Acamas child theme options page which seem to work:

        $cats = get_categories(‘hide_empty=0’);
        foreach($cats as $cat){
        $select_options[$cat->cat_ID][“value”] = $cat->cat_ID;
        $select_options[$cat->cat_ID][“label”] = $cat->cat_name;
        }

        Also needed to remove the original array defined in $select_options, otherwise the other values remained in the drop-down.

        BUT, it doesn’t work if I try to define a custom select box, eg $featured_options. I can get the list of categories but can’t save the option.

        Any ideas? I can’t figure it out as my PHP knowledge is limited to cut-and-paste.

      3. this seemed to work for me , change this:

        // Our select option must actually be in our array of select options
        if ( ! array_key_exists( $input['selectinput'], $select_options ) )
        $input['selectinput'] = null;

        to this:

        $input['selectinput'] = $input['selectinput'];

        now you should be able to save

  19. Thank you so much! I’ve been trying to dive into theme options for the custom themes I build for clients. I’ll give this one a try on my next project.

  20. Hi there,

    thanks for this hack. I spent whole day with modifying this code but I have no luck to add a reset button. Is possible to add a reset function (delete_option or something like that) to get default values? I am confused. Thanks for help.

    1. That sounds like something that might make a good future update to the sample options.

    2. some default values would be nice as well 🙂

    3. I have found a solution for the reset function however it’s not the best one. But good for start. Under this line if ( ! isset( $_REQUEST['updated'] ) ) {
      $_REQUEST['updated'] = false;

      Put this:

      if( isset( $_REQUEST['reset'] )) {
      global $wpdb;
      $query = "DELETE FROM $wpdb->options WHERE option_name LIKE 'option_name'";
      $wpdb->query($query);
      header("Location: themes.php?page=theme_options");
      die;
      }

      Don't forget to modify the option_name to your own option name value.

      And another modification is to add Reset button.

      Under this line
      <input type="submit" class="button-primary" value="" />

      Put this line:

      Well, this works for me. It needs some modification yet, updated message etc., but this is the best I have done for now. Hope it helps someone :). Good luck.

  21. Thank you for this great sample!

    My question is how can I put a input field with tinymce visual editor in it? Thanks for helping me, and probably for others!

    1. The 2. step is not displaying correctly here. I guess it has cut the code for some reason.

  22. I have a Question? Can this same code be used to create a plugin options panel?

    1. The process is very similar. You should check out Planet Ozh’s awesome sample plugin options page.

  23. oh, I am waiting for upload a file/image feature. Will this be possible soon? 🙂

  24. To add in the TinyMCE to this just add these lines below

    function theme_options_do_page() {
    wp_enqueue_script( 'common' );
    wp_enqueue_script( 'jquery-color' );
    wp_print_scripts('editor');
    if (function_exists('add_thickbox')) add_thickbox();
    wp_print_scripts('media-upload');
    if (function_exists('wp_tiny_mce')) wp_tiny_mce();
    wp_admin_css();
    wp_enqueue_script('utils');
    do_action("admin_print_styles-post-php");
    do_action('admin_print_styles');

    Then change the text area to this :


    the_editor(stripslashes( $options['your-variable'] ), $id = 'my_theme_options[your-variable]', $class = 'large-text' );

    That will add the ability to have the TinyMCE on the theme options page.

    1. This worked pretty easily, but the problem I’ve run into is that you can only have one of these on a page, otherwise they conflict with each other. Do you happen to know of a work around for this?

      1. Another problem I’ve been running into with this is that it doesn’t insert tags around the paragraphs, so when I call the content to a page/post it’s all displayed in one big block of text. Anybody have any advice on that?

      2. Yeah, I’ve noticed this too, not the tag part, but the one per page. I assume it would work like any other OOP piece where it needs it’s own instance to run where the_editor() runs one instance for the page. It’s a pain in the ass, but luckily, I haven’t needed more as of yet.

        As for the tags, I’m not sure why you’re not getting the tag output … you should. I know there is an option to turn off on /wp-admin/options-writing.php for WordPress fixing improperly nested tags.

  25. I am trying to integrate this upload function http://www.wptavern.com/forum/themes-templates/1346-creating-upload-function-options-page.html to the sample options page. But have no luck. Any ideas?

    1. Make sure your form is set to multipart and you should be good to go. You also might want to base64 encode your uploads if you want to store them in your db, but I’d suggest uploading the files to the wp-content/uploads/ directory since that’s what it’s there for.

  26. Super awesome! Thanks!

  27. By far the clearest, easy to follow and implement theme options I’ve come across.
    Not to mention how easy it is to add new textareas, checkboxes etc.

    Just perfect!

  28. Thanks a bunch for this boilerplate Ian, you do the community a great service!

    I’m having trouble setting default values for the options, though – for example: I’d like the checkbox (and its option) to be enabled by default, that way users can simply toggle the option on or off. How would I go about implementing this?

    Keep up the great work!

  29. […] Framework plugin. If you’re just including a few options, the developer recommends trying out Ian Stewart’s sample option page instead. But if you’re planning to include multiple options, the plugin will make it much […]

  30. Hey Ian,

    thanks for your great work!

    I’ve run into a problem where I tried to include two sets of radio buttons.

    I’ve posted the question on StackOverflow:
    http://stackoverflow.com/questions/18423736/wordpress-theme-options-page-radio-buttons-not-updating-correctly

    But it just occured to me: Why not ask the author. 🙂
    I appreciate any kind of help.

    1. Hey Nils,

      This post is crazy old and there are way better options for … options panels now. Like the customizer! Otto can tell you how to leverage the customizer for your theme options.

      It will be a better/easier solution for your radio buttons 🙂

  31. Hey,

    I don’t understand what can I do if I want to upload an image (like a logo or favicon). Thanks

    1. Hi there, this post is three years old, and as Thomas pointed out above there are now other methods you can use. Check out his suggestion for other methods of adding theme options to a site.

  32. I, successfully used this Options page in some of my projects. But I’m wondering, how I can manage it to work for multisite? Is there any tweak, I need to make, to make my same theme to work on multiple subsite at a time?

    1. If your multisite network is setup correctly (see: http://codex.wordpress.org/Create_A_Network), the theme should work just fine on multiple sites.

  33. Why not we are using get_template_part() instead of require_once()?

    1. Hi there, when this tutorial was written, get_template_part() was not yet available. We recommend placing theme options in the Customizer these days. 🙂 However, for the sake of this example, in this situation, require_once() would be more appropriate than get_template_part(), because get_template_part() is intended for displaying reusable parts of a template. The theme options page is not really a template.

      1. Thanks for the clarification, Michelle. 🙂