Wordpress Theme Options Framework Ver 2

By Jeremy Clark
Filed In guides, tech, wordpress  |  Tagged , , ,  |  329 views
TOP del.icio.us digg

As I’ve worked more on my theme and increased my coding skills I’ve added to my original theme option framework. I’ve become more aware of best practices of coding and WordPress, a big issue with the original framework was the way options were added to the wp_options database table. Each theme option got it’s own entry in the table, this might be okay for small theme, but I’ve grown to over 40 different options in my Techozoic theme. It was time to optimize, with the new framework the entries added to the wp_options table went from 40 to 2. I’ll continue below with code examples and explanations. As an added bonus I’ve included an example of how to pull your theme options into a external stylesheet, based off of this concept.

Here is the updated framework files:

After you have the controlpanel.php file uploaded to your server into your theme’s main directory you’ll need to add this line to your functions.php file

<?php require_once(TEMPLATEPATH . '/controlpanel.php'); ?>

Now you’ll need to start editing the array values to add your options. The way you add options to the framework is still the same following the below templates.

$options = array (
    array(  "name" => "Radio Selection Set",
            "desc" => "This is a descriptions",
            "id" => $shortname."_radio",
            "type" => "radio",
            "std" => "3",
            "options" => array("3", "2", "1")),

    array(  "name" => "Text Box",
            "desc" => "This is a descriptions",
            "id" => $shortname."_text_box",
            "std" => "Some Default Text",
            "type" => "text"),

    array(  "name" => "Bigger Text Box",
            "desc" => "This is a descriptions",
            "id" => $shortname."_bigger_box",
            "std" => "Default Text",
            "type" => "textarea"),

    array(  "name" => "Dropdown Selection Menu",
            "desc" => "This is a descriptions",
            "id" => $shortname."_dropdown_menu",
            "type" => "select",
            "std" => "Default",
            "options" => array("Default", "Option 1", "Option 2")),

    array(  "name" => "Checkbox selection set",
            "desc" => "This is a descriptions",
            "id" => $shortname."_checkbox_menu",
            "type" => "checkbox",
            "std" => "Default",
            "options" => array("Default", "Option 1", "Option 2")),

    array(  "name" => "Multiple selection box",
            "desc" => "This is a descriptions",
            "id" => $shortname."_multi_select_dropdown_menu",
            "type" => "multiselect",
            "std" => "Default",
            "options" => array("Defaults", "Option 1s", "Option 2s"))
);

Another new feature I’ve added is a theme init script. It’s useful for adding default values to the wp_options table. This code will also pull values already in separate wp_options entries and put them into the single array wp_option, then delete the old entries. Then the code sets a separate value in the wp_options table as a check so the script will only run if it doesn’t find that value. Then the function is added to the dashboard and main page header via the action hook. So the first time any visits a page in the dashboard or on the blog the mytheme_add_options will run, but only the first time.

function mytheme_add_options() {
global $themename, $shortname, $options;
foreach ($options as $value) {
	$key = $value['id'];
	$val = $value['std'];
		if( $existing = get_option($key)){
			$new_options[$key] = $existing;
			delete_option($key);
		} else {
			$new_options[$key] = $val;
			delete_option($key);
		}
}
add_option($shortname.'_options', $new_options );
}

function first_run_options() {
global $shortname;
$check = get_option($shortname.'_activation_check');
	if ( $check != "set" ) {
		mytheme_add_options();
   		add_option($shortname.'_activation_check', "set");
  	}
}
add_action('wp_head', 'first_run_options');
add_action('admin_head', 'first_run_options');

After you have your option page the way you like you’ll need some way of get the variables onto other pages of you theme. You’ll need to add these next few lines to every page on which you plan to use the theme variables. Then the variables will be called like an array with the key being the option id.

<?php
global $shortname;
$settings = get_option($shortname.'_options');
// Options are called like this $settings['option_id'];
?>

Now you can use the variables on this page. The variables will look like this let’s assume you set $shortname = “theme”, then your variables will look like this $theme_radio, $theme_text_box, $theme_bigger_box, $theme_dropdown_menu. Also keep in mind that you can add one than one of any kind of element, you can also rename any of the elements for easier variable management. Where “id” => $shortname.”_radio”, is defined you can change the _radio part to reflect what the option is actually for. To check the value of your multiple selection or checkbox variables you’ll need to use this. Where Item is the value that your checking that is selected or checked.

<?php
if(in_array("Item",$settings['theme_checkbox']));
?>

Now I’ll show how to use your theme options on an external stylesheet rather than placing them in the head of the theme, which is bad web practice. It also has the added benefit of the page being cached by the browser so it will also save on bandwidth.

<?php
global $options, $shortname;
$settings = get_option($shortname.'_options');
//Options will be called like this $settings['shortname_option_name']
<head>
<link rel="stylesheet" type="text/css" media="screen" href="<?php bloginfo('home') ?>/?css=css"/>

<?php
if ( is_singular() ) wp_enqueue_script( 'comment-reply' );
wp_head(); ?>
</head>

This code uses something called a query variable that is registered in the functions.php file like shown below to call the style.php file and allow it to use WordPress builtin functions for calling options. Much cleaner and safer than the $_GET method I used earlier.

<?php

	function add_new_var_to_wp($public_query_vars) {

		$public_query_vars[] = 'css';

		return $public_query_vars;

	}

	function dynamic_css_display(){

		$css = get_query_var('css');

		if ($css == 'css'){

			include_once (TEMPLATEPATH . '/style.php');

			exit;

		}

	}

	add_filter('query_vars', 'add_new_var_to_wp');

	add_action('template_redirect', 'dynamic_css_display');

?>

This registers the query variable called css and if that variable is set to css as it is when the stylesheet is called in the header with the ?css=css appended to the end then the style.php file is included then the everything else is stopped with the exit in the code.

<?php
global $shortname;
header('Content-type: text/css');
header("Cache-Control: must-revalidate");
$offset = 72000 ;
$ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
header($ExpStr);
$settings = get_option($shortname.'_options');
// Variables should be added with {} brackets
echo <<<CSS
/*Style Sheet Start*/
body {
background-color: {$settings['theme_option_color']};
}
CSS;
//More php can go here
echo <<<CSS
/*Style Sheet End*/
CSS;
?>

The style.php file can now use the WordPress function get_option for retrieving options from the database. Once this is done then the option variables will be called as an array with the option id being the key ie: $settings['theme_option_color']

Update

I’ve had a request for adding an upload form to the options page for adding a custom header image. I’ve done this same thing in my Techozoic theme, if you would like to look at it to see a practical use of it you can download it here. Basically you’ll need to add a separate file to process the uploaded files, and the form to upload the files. An example upload file can be downloaded here. Then the form can be added to the options page with this code.

<form enctype="multipart/form-data" encoding="multipart/form-data" action="<?php bloginfo('template_directory') ?>/upload.php" method="post">
<input type="file" name="file" /><br />
<input type="submit" name="submit" value="Upload" />
</form>

You just need to upload the file and make sure it’s in the root of your theme directory and named upload.php. You can also edit the upload.php file to change the restrictions on file size and file type. I’ve set the upload.php file to only accept jpg, gif, and png files under 1 MB which should be fine for uploading header images.

1 Star2 Stars3 Stars4 Stars5 Stars |  (4 votes, average: 4.75 out of 5)
Loading ... Loading ...

16 Comments

  • 1

    Hey Jeremy,

    I’ve tried running v2 of your theme framework, and running into what seems an odd error. After just copying the cp.php into my folder and making absolutely no changes, I’ve tried to go into the theme options on my xampp install. For some reason, the arrays are looping 3-6 times (I didn’t count exactly, sorry). I’m not as versed in loops as I’d like to be, so I can’t troubleshoot here. Should I have included the additional files in the zip folder?

    v1 doesn’t do this continuous loop, so I’m not certain what’s up here. I just wanted to let you know here.

    Thanks for providing such a valuable resource. The theme that I’ve been working on for some friends needs a lot of optioning, and rather than have them hard-code the changes (which they’re entirely capable of), it’s easier to provide them an option to do it in the admin area.

    • 1.1

      Alright I spotted the problem, I was updating the old version I had and for some reason I added a second loop before the original loop. I’ve updated the download with the corrected script if you would like to download again and give it a try. Hope this helps you out.

  • 2

    Would an upload function be possible? For custom headers, etc. Thanks!

  • 3

    Will definitely give it a shot, thank you so much!

  • 4

    Jeremy,
    I downloaded that template and also took a look at the upload.php and I believe I understand the logic behind how this works – would I need to create a separate upload.php for every other type of ‘upload’ element I would have in my template though?. I guess I’m a little confused on the actual display of some of these text/select/radio options. I had been looking at http://www.aquoid.com/news/tutorials/wordpress-theme-options/w-theme-options-setting-and-retrieving/ and that seemed to be what I was looking for, but I wanted the ‘upload image’ option simliar to how WooThemes (http://www.woothemes) does it. Sorry if I’m being confusing and asking for a lot, I just really enjoy using WordPress and would love to learn more about Theme Option pages. I really appreciate it. Thanks!

    • 4.1

      I use the same logic in that aqoid.com uses saving and retriving options from one field in the wp_options table. As far as the upload element if you have one than one place that you would like something saved to then you’ll have to create a different upload file with the path set for each in the file. To display an option you just need to copy and edit the right array block that has the right type then just edit the array values and the other coding in the controlpanel.php file handles looping through the array and displaying the option form. I’ll contact you through email and see if I can help more.

  • 5

    the code to get the theme variables on the page doesn’t work for me :-( i get the following error

    Warning: Invalid argument supplied for foreach()

  • 6

    Thanks for the great tutorial Jeremy it works fine now

  • 7

    Rather than add the code to the top of every page i created a custom function to get the options value here’s the code

    function theme_get_option($name) {
    global $shortname;
    $options = get_option($shortname.’_options’);
    if (isset($options[$name])) {
    return $options[$name];
    } else {
    return false;
    }
    }

    then i can call it anywhere on my theme pages like so

    theme_get_option(‘themeShortName_text_box’);

    is this a better way ?

  • 8

    how can i check if a single check box returns true or false and check the box accordingly instead of multi check boxes ?

  • 9

    i can’t get a single check box working i have tried isset also it shows the word Default at the side of the check box but i would like no options but just a check box to return true or false or maybe on or off is it possible to add this featured ? i created a section like

    elseif ($value['type'] == “checkbox2″) {

    code here for check box

    }

    and added another option for checkbox2 however i could not get it to return true or false :-( help is much appreciated

  • 10

    Forget my last comment and once again thanks for the tutorial i managed to solve it by checking if the value is empty like so

    if (!empty($settings['theme_image_slider'])) {
    include(TEMPLATEPATH . ‘/slider.php’);
    }

Trackbacks / Pingbacks

Leave a Reply

Want an Avatar like seen here. Sign up for Gravatar

Subscribe without commenting