This tutorial aims to put the options made available by jQuery plugin developers to WordPress Administrators.
Building WordPress themes is a craft in itself, it's an additional layer to a Web Designers job. Indeed it is also true, getting the basics from the CMS (title, the_content, the_excerpt etc) means you are a WordPress Theme Developer.
If you build WordPress themes it can become routine to open theme files in your code editor and make changes, however that may involve having access to your work machine and site files for the quickest outcomes.
Allowing configuration of jQuery plugin settings in wp-admin, just makes sense in my World. Much like offering customisation of theme logos and page headers.
This tutorial will utilise the Options Framework by WPTheming to create a theme options page. The options page will present any available settings (within the jQuery plugin) we make available.
Whilst for this example, 3 plugins have been selected namely Tooltipsy, Sea of Clouds (Twitter) and FlexSlider by WooThemes these could be any plugins you use most.
Coupled with WordPress it would be as simple as incorporating a few snippets and files in future themes you develop to have a reasonably granular level of configuration with jQuery powered elements.
Let's go ahead and create the bare bones of our theme. The files required for this tutorial are listed below.

*1 - Denotes sample images used for this tutorial as seen within Twenty Eleven.
*2 - Denotes files within the Options Framework.
This is a very basic header.php file, 3 points of interest here really.
wp_head(); to allow WordPress to bring in jQuery.We are going to register 3 jQuery plugin files later with WordPress wp_footer(); is required for the output.
Between script tags we will initialise the plugins with any additional settings.
Line 3 - A div with class of "tweets" is required for the Tweets plugin to function.
No posts yet.
Finally we use index.php to bring our files together to have an all-be-it very basic but functional theme.
get_header();.The WordPress Loop".get_sidebar();.get_footer();.The above lines should be super familiar to Theme Developers, if you don't know anything about these good luck with your journey. WordPress is the man!
Styles above have been created to position the header, sidebar and main content areas on the page.
Lines 2, 3, 4 and 5 tells WordPress about our theme.
[sourcecode language="css" firstline="1"] div.flexslider { position: relative; height: 276px; } ul.slides li { display: none; } ul.slides li { display: none; } ul.slides li img { max-width: 100%; display: block; } ul.flex-direction-nav li a { position: absolute; bottom: 10px; z-index: 10; padding: 5px; background: #FFF; } ul.flex-direction-nav li a.prev { left: 10px; } ul.flex-direction-nav li a.next { right: 10px; } ol.flex-control-nav { position: absolute; left: 10px; right: 10px; bottom: 10px; text-align: center; } ol.flex-control-nav li { display: inline-block; margin: 0 1px; } ol.flex-control-nav li a { padding: 5px; background: #FFF; display: block; cursor: pointer; } ol.flex-control-nav li a.active { color: #ed4b48; } div.flex-pauseplay { position: absolute; top: 10px; right: 10px; text-align: center; } div.flex-pauseplay span.pause, div.flex-pauseplay span.play { padding: 5px; background: #FFF; display: block; cursor: pointer; } [/sourcecode]Some styles for FlexSlider. Very minimal.
[sourcecode language="css" firstline="1"] ul.tweet_list li { border: 1px solid #CCC; margin: 0 0 5px 0; padding: 5px; overflow: hidden; } ul.tweet_list li a.tweet_avatar { float: left; margin: 0 5px 5px 0; } ul.tweet_list li a.tweet_avatar img { padding: 4px; background: #EEE; border: 1px solid #CCC; } [/sourcecode]In keeping with bare minimum styling for the Twitter stream.
[sourcecode language="css" firstline="1"] .tooltipsy { padding: 5px; background: #333; color: #FFF; border: 1px solid #111; -webkit-box-shadow: 0 0 5px #000; } [/sourcecode]Finally, the tooltip style.

To this point we have brought together a very basic WordPress theme to illustrate proof of concept with the 3 jQuery plugins chosen.
Next we will include jQuery plugins with WordPress conventions to reap the benefits this can bring, such as GZipping and Caching of scripts (if you have suitable plugins installed along-side).
Furthermore we will set-up the Options Framework to work with the theme by utilising functions.php. 3 arrays will be created to hold any settings each plugin ships with that we chose to make available (e.g. Callback functions are something that may possibly be best served within theme files and not generated dynamically, unless you wish to write jQuery within wp-admin!).
These arrays will be iterated over in conjunction with the Options Framework conventions to bring any plugin settings to the theme options page.
is_admin(); to check wether we are within the wp-admin dashboard.$js_path" as a helper to point to the locations of any scripts.wp_register_script(); to notify WordPress of the script name, its path, dependencies (jQuery is passed here and wp_head() will be used to output), version and wether to use wp_footer as the hook or not.wp_enqueue_script(); to add the previously registered script to any WordPress output.add_action(); to attach all scripts to WordPress at runtime, using the function previously created.Let's make sure we include the scripts registered in the previous step with our theme within functions.php.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1" highlight="2, 3"] if(!function_exists('optionsframework_init')) : define('OPTIONS_FRAMEWORK_DIRECTORY', get_template_directory_uri().'/inc/options-framework/'); require_once dirname(__FILE__).'/inc/options-framework/options-framework.php'; endif; function optionsframework_option_name() { $themename = get_option('stylesheet'); $themename = preg_replace("/\W/", "_", strtolower($themename)); $optionsframework_settings = get_option('optionsframework'); $optionsframework_settings['id'] = $themename; update_option('optionsframework', $optionsframework_settings); } function optionsframework_options() { $options = array(); } [/sourcecode]The piece of code above ships with the Options Framework, since we've organised our theme a little differently take note of lines 2 and 3 where we modify the paths slightly.
If you look at the documentation for FlexSlider you'll notice the possible settings available, this is our reference when creating the PHP $flexslider_options array.
Let's take all the options that could reside in the Theme Options page and place them within a PHP multi-dimensional array.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] $flexslider_options = array( 'animation' => array('title' => 'Animation Type', 'description' => 'Select your animation type, "fade" or "slide"', 'type' => 'select', 'class' => 'mini', 'default' => 'fade', 'values' => array( 'fade' => 'Fade', 'slide' => 'Slide')), 'slideDirection' => array('title' => 'Slide Direction', 'description' => 'Select the sliding direction, "horizontal" or "vertical"', 'type' => 'select', 'class' => 'mini', 'default' => 'horizontal', 'values' => array( 'horizontal' => 'Horizontal', 'vertical' => 'Vertical')), 'slideshow' => array('title' => 'Enable slideshow?', 'description' => 'Animate slider automatically', 'type' => 'select', 'class' => 'mini', 'default' => 'true', 'values' => array( 'true' => 'Yes', 'false' => 'No')), 'slideshowSpeed' => array('title' => 'Speed of cycling between slides', 'description' => 'Set the speed of the slideshow cycling, in milliseconds', 'type' => 'text', 'class' => 'mini', 'default' => '7000', 'values' => false), 'animationDuration' => array('title' => 'Animation duration', 'description' => 'Set the speed of animations, in milliseconds', 'type' => 'text', 'class' => 'mini', 'default' => '600', 'values' => false), 'directionNav' => array('title' => 'Enable previous / next links?', 'description' => 'Create navigation for previous/next navigation?', 'type' => 'select', 'class' => 'mini', 'default' => 'true', 'values' => array( 'true' => 'Yes', 'false' => 'No')), 'controlNav' => array('title' => 'Enable slide numbering?', 'description' => 'reate navigation for paging control of each clide? Note: Leave true for manualControls ', 'type' => 'select', 'class' => 'mini', 'default' => 'true', 'values' => array( 'true' => 'Yes', 'false' => 'No')), 'keyboardNav' => array('title' => 'Enable keyboard navigation?', 'description' => 'Allow slider navigating via keyboard left/right keys', 'type' => 'select', 'class' => 'mini', 'default' => 'true', 'values' => array( 'true' => 'Yes', 'false' => 'No')), 'mousewheel' => array('title' => 'Enable mousewheel scrolling?', 'description' => 'Allow slider navigating via mousewheel', 'type' => 'select', 'class' => 'mini', 'default' => 'true', 'values' => array( 'true' => 'Yes', 'false' => 'No')), 'prevText' => array('title' => 'Previous text', 'description' => 'Set the text for the "previous" directionNav item', 'type' => 'text', 'default' => 'Previous', 'class' => 'mini', 'values' => false), 'nextText' => array('title' => 'Next text', 'description' => 'Set the text for the "next" directionNav item', 'type' => 'text', 'default' => 'Next', 'class' => 'mini', 'values' => false), 'pausePlay' => array('title' => 'Pause / Play button', 'description' => 'Create pause/play dynamic element', 'type' => 'select', 'class' => 'mini', 'default' => 'true', 'values' => array( 'true' => 'Yes', 'false' => 'No')), 'pauseText' => array('title' => 'Pause text', [/sourcecode]Now let's take a look at some of the settings available to the Twitter plugin.
[sourcecode language="javascript" toolbar="true" firstline="1"] username: "seaofclouds", join_text: "auto", avatar_size: 32, count: 3, auto_join_text_default: "we said,", auto_join_text_ed: "we", auto_join_text_ing: "we were", auto_join_text_reply: "we replied to", auto_join_text_url: "we were checking out", loading_text: "loading tweets..." [/sourcecode]As a PHP array using the same conventions as we did with $flexslider_options.
Finally the Tooltip settings available.
[sourcecode language="javascript" toolbar="true" firstline="1"] alignTo: // 'element' or 'cursor', offset: // [x, y] [0, -1], content: // 'Custom tooltip content', show: // Any jQuery animation, showEvent: // Callback function n / a, hide: // Any jQuery animation, hideEvent // Callback function n / a, delay: // In milliseconds 200 Set to 0 for no delay css: // Custom CSS className: // CSS Hook [/sourcecode]... and as a PHP array using the same conventions we get...
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] $tooltip_options = array( 'alignTo' => array('title' => 'Alignment', 'description' => 'Should the tooltip be fixed or follow the cursor when hovered', 'type' => 'select', 'class' => 'mini', 'default' => 'element', 'values' => array( 'element' => 'Fixed to element', 'cursor' => 'Follow the cursor')), 'content' => array('title' => 'Content', 'description' => 'Useful for HTML inside tooltips since you can’t put HTML in title attributes', 'type' => 'text', 'class' => 'mini', 'default' => '', 'values' => false), 'delay' => array('title' => 'Hover delay', 'description' => 'Set to 0 for no delay', 'type' => 'text', 'class' => 'mini', 'default' => '0', 'values' => false), 'css' => array('title' => 'Custom CSS', 'description' => 'Useful if you want to keep styles together with plugin settings', 'type' => 'textarea', 'class' => 'mini', 'default' => '', 'values' => false), 'className' => array('title' => 'CSS Class', 'description' => 'In case .tooltipsy doesn’t work for you', 'type' => 'text', 'class' => 'mini', 'default' => 'tooltipsy', 'values' => false) ); [/sourcecode]Now that the plugin settings have been mimicked as PHP arrays we can keep these as a snippet and re-use in future theme theme development should the need arise. In the event the plugin is updated the snippet can be updated pretty effectively.
I prefer to offload these arrays into their own files for future usage. Whichever plugins you use in a theme it will be a case of grabbing the settings file, setting up the options framework, and outputting within your theme.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] include 'inc/options.flexslider.php'; include 'inc/options.tooltipsy.php'; include 'inc/options.tweets.php'; [/sourcecode]Now that the arrays have their own home make sure to include each within functions.php as required.
With that in mind let's move on and create a panel for FlexSlider within the Theme Options page.
Using the Options Framework this is done with the following code.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] $options[] = array( 'name' => __('Flex Slider', 'options_framework_theme'), 'type' => 'heading'); [/sourcecode]
To create an option for each setting we add to the $options array.
First let's make sure we can have global access to each array by setting their scope within the optionsframework_options() function...
Using the $flexslider_options array and a foreach loop we can create an option / input at each iteration to match the settings.
The $options[] array is a convention of the Options Framework and explanations are loosely cited from the example files provided by the Author below.
name - Human readable title, outputted within Theme Options page.desc - Human readbale description, describing the particular option.id - Unique identifer (we will use this for theme output).type - Possible field types: 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.std - Default input value.class - Possible values: mini, tiny, smalloptions - Array of possible values for supported fields.On line 3 we use the ternary operator to define a value if set. Some flexibility was considered whilst creating the arrays to hold any settings. This will allow for custom titles to be displayed along with each option whilst defaulting to the setting name if none provided.
Line 5 an incremental value is used to store a unique identifier with each option.
All other lines are standard values which should be followed as directed by the Options Framework Author taken from our settings array using corresponding keys.

It is now a case of lather, rinse and repeat for $tweet_options and $tooltip_options.
First a new panel is created.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1" highlight="6"] $i = 0; foreach($tweet_options as $key => $value) : $options[] = array( 'name' => (isset($value['title'])) ? $value['title'] : $key, 'desc' => $value['description'], 'id' => 'tweet_opt_'.$i++, 'type' => $value['type'], 'std' => $value['default'], 'class' => $value['class'], 'options' => $value['values'] ); endforeach; [/sourcecode]Next we loop over those settings and add to the $options[] array. Notice the value of id, this will be useful later.
One more time...
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] $options[] = array( 'name' => __('Tooltipsy', 'options_framework_theme'), 'type' => 'heading'); [/sourcecode]First we create a new panel and give it a heading.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1" highlight="5"] $i = 0; foreach($tooltip_options as $key => $value) : $options[] = array( 'name' => (isset($value['title'])) ? $value['title'] : $key, 'desc' => $value['description'], 'id' => 'tooltip_opt_'.$i++, 'type' => $value['type'], 'std' => $value['default'], 'class' => $value['class'], 'options' => $value['values'] ); endforeach; [/sourcecode]Finally we set the values, again the only change here is the settings array being passed and the id value.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] return $options; [/sourcecode]As directed by the Options Framework we lastly return the $options array which is now populated with the plugin settings and outputted as options for the chosen 3 plugins.
The optionsframework_options() function is now complete.
The Options Framework should now be functioning with the theme nicely which will present 3 panels within the theme options page and any corresponding options.
Plugin settings were registered with the Options Framework by iterating over the arrays created, we'll take a similar approach as we output theme options values to the theme in the final step.
First let's make sure we have access to the settings created and offloaded to their relevent files namely options.flexslider.php, options.tooltipsy.php and options.tweets.php.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] global $flexslider_options, $tweet_options, $tooltip_options; [/sourcecode]The plugin settings are included with functions.php at each page load, we can gain access to these previously created setting arrays by making them global much like we did within functions.php.
With that let's consider the output required from each plugin used.
A pretty standard object containing settings which can be passed to the plugin upon initialising.
Line 7 as highlighted will remain the same, outputting a dynamic object with any settings is what we're looking for here.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] of_get_option('option_name') [/sourcode]To retrieve any stored values from the Options Framework the Author has created a helper function which accepts the option id as a parameter to retrieve its value. Back in Step 6 an option id was created using plugin_opt_n where n is a number starting from 0 to infinity. This is helpful and index order is unimportant.
A foreach loop will do the trick here to grab that data using a counter again to obtain the key and values dynamically in conjunction with the ever helpful helper function (tautology anyone?). Let's get to it.
$key is the plugin setting, its value is outputted with a colon as we build the object.Once more we lather, rinse and repeat to finish up with the tutorial.
Retrieval of settings.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] var $tweet_options = { $value) : $option_value = of_get_option('tweet_opt_'.$i++); echo $key.": "; if($i == $count) : if($option_value == 'true' || $option_value == 'false' || is_numeric($option_value)) : echo $option_value."\n"; else : echo "'".$option_value."'\n"; endif; else : if($option_value == 'true' || $option_value == 'false' || is_numeric($option_value)) : echo $option_value.",\n"; else : echo "'".$option_value."', \n"; endif; endif; endforeach; ?> }; $(".tweets").tweet($tweet_options); [/sourcecode]Retrieval of settings.
[sourcecode language="php" toolbar="true" htmlscript="true" firstline="1"] var $tooltip_options = { $value) : $option_value = of_get_option('tooltip_opt_'.$i++); echo $key.": "; if($i == $count) : if($option_value == 'true' || $option_value == 'false' || is_numeric($option_value)) : echo $option_value."\n"; else : echo "'".$option_value."'\n"; endif; else : if($option_value == 'true' || $option_value == 'false' || is_numeric($option_value)) : echo $option_value.",\n"; else : echo "'".$option_value."', \n"; endif; endif; endforeach; ?> }; $('.tooltip').tooltipsy($tooltip_options); [/sourcecode]Now you should be able to configure the plugins via the Theme Options page and see those changes reflected immediately within the theme.
Whilst many may not see a direct benefit to this tutorial, I've found this technique useful when any Administrators of a WordPress site need some access to finite tuning of existing theme features, the FlexSlider example in particular here showcases this technique well.
Having a Theme Options page has many practical uses, configuring jQuery plugins is one example however the Options Framework gives lots of potential. For example you could use it for logo uploads with its upload field type or you could use it to configure typography within the theme with the very helpful typography fields (a combination of select inputs and a colour wheel). The possibilities are only limited to your functional brief.
I hope this tutorial yields some improvements to your workflow and any questions related to the implementation of the Options Framework and theme here please do ask.