WordPress Theme Options Framework Ver 2
By Jeremy Clark
guides, tech, wordpress |
php, theme, tips, wordpress | 1,976 views
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.




| (9 votes, average: 4.89 out of 5)
EsteWeb
May 26th 2010 @ 6:47 pmFirst off, thank you very much for this tutorial, it’s really helped me a lot with my current project and I know it will be useful knowledge on future ones. Now on to my question: Say I wanted to be able to make it so that I can choose categories for certain pages (or even call upon pages for certain options), how would I go about doing that? I’m having a tough time trying to figure it out, it’s driving me nuts…
Wok Doan
Jun 30th 2010 @ 12:33 amIs there in way to
to have a the dynamically generated style sheet have a name appended.
With the current provided sample code
http://www.fakedomain.com/?css=css, would work
but
http://www.fakedomain.com/directoryname/filename.css?css=css
would provide a 404 error in the response headers, even though you can pull up the page in a web browsers
Any thoughts?