The Options Framework Theme has all the code included to build a out a full featured options panel. It’s a bundled version of the Options Framework Plugin for those folks who want to build the options directly into the theme (rather than relying on a plugin).

This project was released long before the Customizer was a part of WordPress. The Customizer is now the recommended way to add theme options and you can read more about it here.

Available Options

  • text
  • textarea
  • checkbox
  • select
  • radio
  • upload (an image uploader)
  • images (use images instead of radio buttons)
  • background (a set of options to define a background)
  • multicheck
  • color (a jquery color picker)
  • typography (a set of options to define typography)
  • editor


Copy the “inc” directory, options.php, and the code snippet in functions.php from the “Options Framework Theme” into the theme of your choice. Hack away. You can also watch the video above to see how it is done.

When to Use Theme Version vs. Plugin Version

The code is 99% the same between the plugin and theme version. If you can do what you need with the plugin version, I think that’s the best route. If you find that you need to make significant modifications that aren’t possible with the plugin, go ahead and use the theme version.

Change the Menu Location

It’s highly recommended that you leave theme options under the “Appearance” menu where users expect them.

But, if you do decide to change the menu location it will break the media uploader. This is because the media uploader scripts are enqueued on $of_page= ‘appearance_page_options-framework’ in options-medialibrary-uploader.php. If you change the name or location of the menu, you’ll need to update the hook to be accurate, e.g. $of_page= ‘toplevel_page_options-framework’ and those scripts will load properly again.

Sanitization Filters

If you’re interested in how the options data is verified, or if you’re wondering why your script and embed tags are stripped out in the Options Framework, read this post.

Can I Use This Code in Commercial Themes

Yes! This code is 100% GPL. Please read the included license for more details.

Development Version on GitHub

The development version of the Options Framework Theme is available on GitHub.

Additional Tutorials

The demo themes associated with these tutorials are also available on GitHub.

862 thoughts on “ Options Framework Theme ”

    1. In the HTML of the uploader, I noticed the name was wonky. It was showing as “slideshow_image1” instead of “optionsframework[slideshow_image1]”.

      In optionsframework_medialibrary_uploader, I replaced the $option_name = $optionsframework_settings[‘id’]; line with the same check you do in optionsframework_fields():

      if (isset($optionsframework_settings[‘id’])) {
      $option_name = $optionsframework_settings[‘id’];
      else {
      $option_name = ‘optionsframework’;

      It is a hack, but it works. I don’t know why this didn’t effect me before.

  1. Having problems with media uploader, just getting a white screen in the thickbox.

    Moved the options to a top level menu, made the changes as above in the medialibrary-uploader and options-framwork files. Reset browser, no plugins active.

    The only other change I made was to rename “Theme Options”. Could this be the problem? Any help on where to debug would be much appreciated.

      1. I finally found the problem. I have a custom posttype and was using the add_action (‘admin_head’, “my_icons”) function to add a 32×32 icon. Every time I add that in, the media uploader breaks everywhere.

        Extremely strange, and I’ve opened it up for discussion on

        So solved, definitely not the framework :-)

        If anyone else runs into this, make sure you aren’t adding 32×32 icons using that add_action method.

  2. Out of curiosity, is there a way to get the attachment ID from a file uploaded, so I can use the thumbnail sizes? (or just pass a thumb size?)

  3. Hi,

    Thanks for this plugin/theme! I was actually surprised there’s not something like this built-in into WordPress :)

    I was curious though, why didn’t you merge the importer/exporter code? It’s pretty useful, and seems to be mostly well-coded?


    1. I’m trying to keep the codebase as slim and maintainable as possible. If it is not something that I think 80% of users/developers will use- I’m a bit wary of adding it in. See the WordPress philosophy under “Clean, Lean and Mean”:

      A couple people have asked about an export function, but it hasn’t been highly requested. What is your use case, if I might ask?

      1. Hi Devin,

        I’m building a theme that’s very versatile and has a fairly high number of options (though I’m trying to abstract some of them from the end-user as much as I can).

        I’m also deploying a dozen of installs as demo and staging sites for the theme (think,, etc.) and want to automate that as much as I can. I’m looking into the new WP CLI too, but exporting/importing theme settings seem more straightforward from the theme itself.

        I think it makes sense for the end-user as well: you can import settings from a demo site and then just change what you need to change, etc.

        More generally than this precise feature, I think it would be cool to have more extensibility capabilities built in the Framework (so that people can distribute packaged “plugins” to your framework, so to speak). I will be suggesting a few things like this on Github in the next couple of days, I hope you’ll like them! (for instance, I would like to be able to configure — not extend — some options in `options.custom.js`).

        Thanks for your terrific work on this framework,


  4. Hi,
    is possible to add a on/off button? With this button i should be able to show or hide individual options in options panel.

  5. WP (3.3) debugger throws “Notice: wp_enqueue_script was called incorrectly. Scripts and styles should not be registered or enqueued until the wp_enqueue_scripts, admin_enqueue_scripts, or init hooks…blah, blah” error. Any idea how to get rid of it? …or is there any more convenient method to enqueue required scripts?
    Thanks a ton for all of your efforts Devin!!!

  6. Hi Devin,
    Is it possible to have a 2nd instance of the options framework to capture different theme options. I don’t want this to be additional tabs, but a separate “page” with different tabs.

  7. Hi Devin,

    Is it possible to pass any additional variables to the textarea option? In particular, I need to default the rows and columns larger. Is this possible?

    1. If you’re using the theme version, you can edit it directly. You can also pass a parameter in the option for columns: “options” => array(‘cols’=>’100’), but it looks like the option for columns needs to be added too.

      1. Thanks Devin, I see it. In admin-interface “rows” is hardcoded at the moment, but I think I know how to update this. Will you be adding this to a future version?

  8. I think the fully featured media library is not a good choice for uploads. Something much simpler, that just allows the user to upload an image would be a better choice, in my opinion. I’m trying to implement something like that.

    If anyone has some suggestions, let me know!

    1. You can look at the very early commits on this project. It originally used an ajax uploader- but I switched to more closely match the WordPress interface.

      1. Thanks for the response, Devin!

        Actually, I think there’s a problem with the media uploader WP 3.3.1. The function optionsframework_mlu_js_popup () is not tweaking the media uploader thickbox, removing the gallery settings and changing other stuff.

        Check it out!

  9. Using the image uploader, what is the best way to handle image resizing on upload? Say you had a slider and used this to upload images. Obviously I could just use CSS to declare the size, but is there a way to have WordPress resize/crop the images (like how you can define sizes of thumbnails and how you want them to be cropped). Thanks!

  10. Hey Devin, when I take the two options to create a hidden text field from options.php in the demo version of the theme, and drop them into the options.php of my theme, they only work if I keep the same IDs as you have. Does that make sense?

    What ties them together so that I can give them IDs more relevant to my theme?


    1. Look in functions.php for “Options Check”. You’ll see that there is custom jQuery code there that makes that functionality happen. You’ll need to edit the div ids in that code if you want to change the option ids.

  11. first of all, great script. i’m planning to use it in my future projects soon. just a siple question Devin, how do I disable the sanitizing of the values? apparently i still need the html tags on simple text inputs.

  12. Great stuff here, for the life me I cannot get a thumbnail from an uploaded image though. This seems to exactly what I want :

    And so here is my code:

    get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE guid = '$bio_image'" ) );
    $theID = $thepost->ID;
    echo wp_get_attachment_image( $theID, 'thumbnail' ); ?>

    Nothing comes back. Have tried in various places in my theme, no luck, I can’t work it out.

  13. Hey Devin,

    I really love the framework. Extremely good job.
    I got one question:

    Is it possible somehow that a set of options will appear only when a specific checkbox is ‘checked’?

    Thanks in advance,

      1. I guess I have an older version of the framework with the old UI. It’s been used in a theme I bought a while ago.

        Is this function available in the older version?
        If not, anyway to update the version without breaking it?

        Thanks in advance

      2. Another question if I may.

        Is it possible somehow to replace the uploader from WP media library to the simpler one used in previous version?


      3. You’re welcome to make a fork and revert to the older version. Eventually WordPress will tackle media and the UI will be better- but for now I am planning to keep the current interface.

  14. Hi,

    First of all: thanks for the amazing framework!

    I have a small question: I would like to put the options.php file inside the admin folder. Is this possible? Because I see in options-framework.php you’ll have to change the form action path.

  15. Hi Devin,

    I’m trying to add some kind of on-the-background options, that have to be set when certain options are updated, but are not shown between the options menu. Is there an easy way to do this? Maybe a “do-not-display” type?

    Thanks for this amazing framework.

  16. thanks for your time and effort and for making this available to us! theme options always caused a huge nightmare in the past… rock on! :)

  17. Hi Devin,

    I really love the framework. Amazing job!

    I was playing with the “optionsframework_custom_scripts” function to hide and show option fields. Thanks to your example I’ve got it working on my checkboxes, but is it possible to attach it to dropdown menu’s (select)?

    I already have this code:
    jQuery('slider_effect').change(function() {

    if jQuery('slider_effect').val("Fade")) {

    What I want to achieve is that when the user selects the option “Fade” in the dropdown, the input field “Fadespeed” displays. At this moment, the correct input field appears and saves, but when the options page refreshes, all the fields are displayed, even when “Fade” isn’t selected.

    Thanks in advance.

      1. Thanks!
        I’ve fixed it with the following code:

        if (jQuery('#slider_effect option:selected').val() == "slide") {

        It works perfect!

  18. Hey Devin,
    I got an issue when trying to use the ‘select’ type when the options are a list of fonts in a directory.

    The problem is that the “value” in each “option” is the array number (1,2,3,4,5,etc), and the actual font file name isn’t passed. So when I try to dynamically use the selected font, it returns the number, instead of the wished font name.

    Any idea how I can solve this? Here’s the code:

    Any assistance would be appreciated,

    1. You should be able to define the key to whatever you want. There’s no reason it needs to be 1,2,3,4,5. See $test_array in the Options Check theme (in options.php).

      1. Yes I know I can manually define the keys, but in my case the $key needs to be the JS filenames, which is dynamic according to the files in the given directory.

        Is it possible the pass the $value not as the value tag defined in each option tag, but rather the option itself?

        Currently it’s working like this:
        [option value=”1″]file1.js[/option]

        Is it possible the it will work like this?


      2. I did, and therefor I tried to change the defenition in the options-interface.php file. I tried to remove the “value” tag from the output but then the option select just isn’t saved.

        I even tried to change $val == $key to $val == $option
        and value=”‘ . esc_attr( $key ) . ‘” to value=”‘ . esc_attr( $option ) . ‘”, but even here, the option selected isn’t saved for some reason.

  19. Hi,

    I realize I posted in the wrong section since I’m using the options framework theme. When using the code below, a text editor does appear in the options panel. However, whatever I type in it is not saved. I’m probably doing something wrong but I can’t figure out what exactly.

    $options[] = array( "name" => "Default Text Editor",
    "desc" => "Here is the description.",
    "id" => "example_editor",
    "type" => "editor");

    Thanks !

    1. I haven’t moved that code into the theme version yet. It’s still being tested. In the plugin version (with Options Check), it is working for me. Is it not working for you?

    2. // Editor
      function of_sanitize_editor( $input ) {
      global $allowedposttags;
      $output = wp_kses( $input, $allowedposttags );
      return $output;

      add_filter( 'of_sanitize_editor', 'of_sanitize_editor' );

      Add this to options-sanitize.php maybe helps …

  20. I’m trying to create a term selector for a custom taxonomy, but it only pulls in one term. Here is what I’ve got:

    // Pull all the product categories into an array
    $options_productcategories = array();
    $options_productcategories_obj = get_terms('productcat');
    foreach ($options_productcategories_obj as $procategory) {
    $options_productcategories[$procategory->term_ID] = $procategory->name;

    Can anybody help?

    1. So, this works for me:

      // Pull all the categories into an array
      $options_categories = array();
      $options_categories_obj = get_terms('post_tag');
      foreach ($options_categories_obj as $category) {
      $options_categories[$category->term_id] = $category->name;

      I left that var_dump in there so you can see if you are actually getting returned terms.

  21. Hi, this is excellent! Only one question, why can I get the upload images box appear only when I use add_theme_page and it doesn’t work if I change it for add_pages_page or add_menu_page?

    Thanks a lot!
    P.S.: Sorry for my english, I’m from Uruguay :)

    1. $posts = get_posts();
      $posts_list = array();
      foreach($posts as $post) {
      $posts_list[$post->ID] = $post->post_title;

      something like this?
      and then add “posts_list” to “options”…

  22. Hello,
    I need the select box, I will return the string value and not the ID value, how can I do, below that I have in my options array.

    $options[] = array( “name” => “Home Sidebar”,
    “desc” => “you can select the sidebar of home page here.”,
    “id” => $shortname.”_home_sidebar”,
    “type” => “select”,
    “options” => $active_sidebars,
    “std” => “Blog Sidebar”

      1. If you don’t know the name of the sidebar, how would you be able to generate an option that has the name of the sidebar?

      2. I was hinting at the answer, but maybe I should just be specific. If you are able to generate $active_sidebars, you know all the keys and values. Just use the variable $active_sidebars again when you need to output the value somewhere else. e.g. $active_sidebars[(of_get_option(‘sidebar’)]

    1. I’m not quite sure what you mean. You can store any key/value pair that you want. Save the key the same as the value if that’s what you want returned.

  23. Hi Devin, nice work! I have just a little problem:

    I want this in the admin sidebar:

    -toplevel menu -> sublevelmenu1 => option panel1
    -> sublevelmenu2 => option panel2
    -> sublevelmenu3 => option panel3

    I read your “change the menu location” note but i didn’t succeed to have a clean panel with color picker and others media uploaders.

    Is it possible? How can i do that? thanks

      1. Ok so i’ll forget this idea and concentrate on one top level menu with some tabs in. Thanks a lot!

  24. Hi! Having a problem with font-face in Typography. When I set the font-face it resets on default value (Arial). Have you ever had situation like this?
    Thanks a lot.

      1. I haven’t had a problem with the font-face in Typography re-setting to the default value, however I noticed that the font-size re-sets itself to the default 9px after saving changes.

        I also noticed that the font size was not being applied in the browser so in index.php I changed:

        font:’.$typography[‘size’] .


        font-size:’.$typography[‘size’] . ‘px;

  25. What If I Want To ADD Custom Icons For Every Menu inside the frame ,, i maen some thing like this ,,

    $options[] = array( “name” => “Main Setting”,
    “icon” => “main.png”,
    “type” => “heading”);

    which Display the in menu like this ( [icon as img] Main Setting) .. ??
    Like Woo theme frame work ,,

    1. For the tabs? The easiest way is probably to just do it via options panel CSS. If you need it defined in the option, that’s customization land and you’re on your own. :)

  26. hello, is it possible choose not images media in “media library” in uploader? not when i choose for example PDF file i see white screen.

  27. For the colorpicker, is there a way when calling the option to exclude the # sign? Right now it’s outputting as #111111 when I want it to output as 111111.

    Great job on the theme by the way, this is a lifesaver.

  28. Client uses phpthumb and a value in phpthumb will only accept the hex value without #. Working on workaround that doesn’t include phpthumb :)

    Also, that’s what I figured, although the original colorpicker.js seems to accept non # values but I couldn’t figure a way to revert it back to that.

  29. in start of loop ..

    when i try to add selected option it give an error ..

    i make it like >
    <?php query_post('cat=’);?>

    so what is the right way ?

  30. query_posts(‘cat=1&showposts=4’);

    when i try to add option like

    query_posts(‘cat=echo of_get_option( ‘mhgoz_mcl_tb1_tit’ )&showposts=4′);
    it gives error

  31. Hi Devin, Thanks a lot making theme options that easy for guys like me, Well I have used the framework in few themes and I love it :)

    Only thing that I want to do with it is that is it somehow possible to show theme options and a separate menu item instead of under appearance settings

    Thanks for help in advance :)

  32. Great plugin Idea!!! I just tried installing the Options Theme (versus the plugin) and immediately ran into some problems. I did move over the entire admin folder, the functions.php snippet, and options.php. It IS working in that the data is spitting out on the front end correctly. BUT the dashboard admin area appears as if the javascript is not loading. The tabs do not work, the media uploader doesn’t work, color-picker doesn’t load, and the Basic and Advanced settings are stacked (instead of in tab-form). Lastly, the styling isn’t correct easier, as all of the inputs are smushed close together with no padding. It seems that the js isnt loading. Any idea why this is happening? I tried installing this on a few of my local themes with the same problem each time.

  33. Hello Devin,

    Thanks a lot for this framework and I use this for few my themes, but 3 of my theme users experiencing an issue, when they hit the save button it says options saved but nothing changed..

    Can you explain why this happens?

  34. Hey Devin, thanks for the amazing framework. Is it possible to automatically populate the wp_options table with all of the default options when the user installs the theme for the first time?


      1. Yes!
        Please don’t store the dafault value in database on activation.

        And if you ever do this, please make it filterable, so if we don’t want it, we can just deactivate it.

      2. hmm..
        i read otto’s comments again, but i don’t really understand it.

        is that means,when user click restore default, it will delete the database?

        or if for example user only change 1 of 5 options, then only 1 options saved in database?

        or both?

        what do you think about modifying of_get_option and get the default value from optionsframework_options when there’s no database yet?

      3. Good question about what to do when user clicks “reset”. Not sure, I supposed either would work.

        But I think the main concern was about options automatically getting set on activation. In that case, the user would actually be navigating to the options page and setting them.

  35. Dear Devin,

    Tim here and I need some help. I’m trying to create a magazine style theme for a client using your theme options framework.

    Specifically how to your the category select option. The website mockup is located here:

    I can pull in the category title but not the post information using the same option as the title div.

    Would you be so kind as to offer a solution? Thanks in advance for all your help.


  36. Dear Devin,

    Tim here, I am using the category option as described to bring in the blog title, but becuase of the way I have it bringing in the most recent post it won’t work in the same way.


  37. Hi!

    Thank you for this theme! I try to use ‘Options Framework Theme 1.0’ on WP 3.3.2. and I have issue with uploader. In general it works great, but it does not show default value ‘no entry’. It means that I can upload image and it becomes visible on web site, but when I remove it default value ‘no entry’ does not appear. Where could be the problem?

    Thank you for advice!

Leave a Reply

Your email address will not be published. Required fields are marked *