WP Theme Options: Bells and Whistles

 

In the previous two sections we looked at defining different types of options, and setting and retrieving them. In this section we will look at supercharging your theme options and making them ready for prime-time.

At the heart of this exercise are very simple concepts:

  1. Better code organization
  2. Visually appealing styles

Better code organization


We started with a barebones list of 5 options ($mnt_header_background_image, $mnt_body_background_color, $mnt_sidebar_alignment, $mnt_nav_pages and $mnt_custom_analytics_code) in the prior sections. But as you add more customization features to your theme, this list is going to grow. And when that happens, you will find it ungainly to maintain the whole list of options in functions.php. At that time it is a better idea to branch off a separate file, solely for options. Let’s say we have created this file “theme-options.php” in a folder called “admin”. You can include this file in your functions.php file in the following manner:

include_once (TEMPLATEPATH . "/admin/theme-options.php");

Every WordPress theme needs to have a style.css file bundled with it. This contains definitions for all your styles along with some metadata about your theme. Now, if you want to have your theme options govern the stylesheet, you need to have PHP code in your stylesheet. For this purpose here is what we will do:

  1. Create a new file called custom-styles.php
  2. Have it included in header.php, after the style.css declaration.

The trick here is to make the PHP file custom-styles.php spit out CSS styles. This is really easy to do:

<?php
global $options;
foreach ($options as $value) {
    if (get_option($value['id']) === FALSE) {
        $$value['id'] = $value['std'];
    }
    else {
        $$value['id'] = get_option( $value['id'] );
    }
}
?>
body {
    background-color: #<?php echo $mnt_body_background_color;?>;
}
<?php
    if (isset($mnt_header_background_image)) {
        $header_bg_url = " url($mnt_header_background_image) ";
?>
#header-container {
    background-image: <?php echo $header_bg_url;?>;
}
<?php
    }
?>

To include this in the blog header, simply add this PHP code to header.php, some place after the call to include style.css:

include_once (TEMPLATEPATH . '/custom-styles.php');

Visually appealing styles


The next step is to make the options page look better. Naturally this involves a stylesheet. Plus, we will make use of the “category” and “parent” elements that we added in the options array, to group our options.

First up, we will create a stylesheet called admin.css in the admin folder. We will define all the styles we need for our options page:

.mnt-options {
	width: 1010px;
	padding: 0px;
	font-family: Tahoma, "Trebuchet MS", Trebuchet, Arial, sans-serif;
	display: inline-block;
	float: left;
	margin-top: 10px;
}

* html .mnt-options {
	width: 1020px;
}

h2.mnt-header-1 {
	display: inline-block;
	width: 100%;
	height: 30px;
	padding: 5px 0px 5px 10px;
	background-color: #444; /*#0052a4;*/
	font-family: Tahoma, "Trebuchet MS", Trebuchet, Arial, sans-serif;
	font-style: normal;
	font-weight: normal;
	font-size: 18px;
	text-shadow: none;
	color: #eee;
}
h3.mnt-header-2,
li.mnt-header-2 {
	display: inline-block;
	width: 100%;
	height: 30px;
	line-height: 30px;
	vertical-align: middle;
	padding: 0px 0px 0px 10px;
	background-color: #888;
	font-family: Tahoma, "Trebuchet MS", Trebuchet, Arial, sans-serif;
	font-weight: bold;
	font-size: 15px;
	margin: 0px 0px 0px 0px;
	color: #eee;
}

h3.mnt-header-3,
li.mnt-header-3 {
	display: inline-block;
	width: 100%;
	height: 30px;
	padding: 5px 0px 5px 10px;
	background-color: #AAA;
	font-family: Tahoma, "Trebuchet MS", Trebuchet, Arial, sans-serif;
	font-weight: normal;
	font-size: 14px;
	margin: 0px 0px 0px 0px;
	color: #000;
}
.mnt-section {
	display: inline-block;
	width: 100%;
	padding: 10px 0px 10px 10px;
	overflow: hidden;

	background-color: #fff;
	margin: 5px 0px 5px 0px;
	border: 1px solid #c0c0c0;
}

.level-1,
.level-3,
h3.mnt-header-2,
.mnt-section {
	-moz-border-radius: 5px;
	-khtml-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
}

.mnt-section h3 {
	border-bottom: 1px dotted #c0c0c0;
}

.mnt-section .mnt-left {
	width: 20%;
	float: left;
	padding: 0px 15px 0px 5px;
}
.mnt-section .mnt-right {
	width: 75%;
	float: left;
}
.mnt-section img {
	border: none;
}
.mnt-section .mnt-radio {
	display: inline-block;
	padding: 5px;
	width: 380px;
	margin-right: 10px;
	float: left;
}
.mnt-section input[type="radio"] {
	margin-right: 10px;
	border: none;
	vertical-align: middle;
}
.mnt-section input[type="checkbox"] {
	margin-right: 10px;
	border: none;
}

.mnt-checklist {
	height: 200px;
	width: 400px;
	overflow: auto;
	margin-top: 20px;
}
.mnt-checklist li:hover {
	background: #eee;
}
.mnt-checklist .depth-1{
	margin-left: 15px;
}

.mnt-checklist .depth-2{
	margin-left: 30px;
}

.mnt-checklist .depth-3{
	margin-left: 45px;
}

.mnt-checklist .depth-4{
	margin-left: 60px;
}

.mnt-checklist .depth-5{
	margin-left: 75px;
}

.mnt-options .color-picker { 
	padding: 20px 0px 0px 20px;
}

.mnt-options input[type="text"] {
	width: 400px;
}

.mnt-options input[type="text"].color {
	width: 200px;
}

.mnt-options textarea {
	width: 400px;
	height: 200px;
}

.mnt-options select {
	width: 250px;
}

The above list will suffice for now.

Tabbed Options


Now we will group our options into different tabs. This feature is very useful if you have a large number of options. To implement this functionality we will use a jQuery library. This is easy because jQuery is included in WordPress distributions.

But before that, let’s tweak our create_form and create separate forms for each group.

    <script type="text/javascript">
        /* <![CDATA[ */
        $j = jQuery.noConflict();

        $j(document).ready(function() {
            // setting the tabs in the sidebar hide and show, setting the current tab
            $j('div.suf-options div').hide();
            $j('#<?php echo $category;?>').show();
            $j('#<?php echo $category;?> div').show();	
            // The above is needed because #theme-selection has children divs which are hidden by the hide() call
            $j('div.suf-options ul.tabs li.<?php echo $category;?> a').addClass('current-tab');

            // SIDEBAR TABS
            $j('div.suf-options ul li a').click(function(){
                var thisClass = this.className.substring(0, this.className.indexOf(" "));
                $j('div.suf-options div').hide();
                $j('#' + thisClass).show();
                $j('#' + thisClass + " div").show();
                $j('div.suf-options ul.tabs li a').removeClass('current-tab');
                $j(this).addClass('current-tab');
            });
        });
        /* ]]> */
    </script>

Enhancing “Save” and “Reset”


Lastly, we will modify our “Save” and “Reset” functionality to support partial saves and partial resets for the theme options.

  8 Responses to “WP Theme Options: Bells and Whistles”

Comments (8)
  1. Great tutorial i’m gonna try this on my next build thanks

     
  2. Hi Sayontan,
    is there any chance of you making the code used in these tutorials available for download ? because my tabs don’t work

     
  3. Wow. I can only applaud. This is theme options on STEROIDS! really awesome work. thank you so much for sharing. i can’t wait to implement some of this!

     
  4. i think i cannot post tags. I am sure it is a simple procedure but I have messed up a few times and broken links show up on Google now! How can I post tags on a post? Please help! Thank you,
    FayFIL2A

     
  5. Hello Sayontan,

    Thanks for sharing these tutorials! It is really great, that you you help people with your ideas and know-how!

     
  6. Hi Sayontan,

    I love the versatility of Suffusion, I am a big fan.

    Question can I add target_blank into the navigation-menu.php
    and would that go into

    if ($pages_style == 'rolled-up' &amp;&amp; count($page_args) != 0) {
    			$page_args['title_li'] = "<a>" . $page_tab_title . "</a>";

    just before the <a href=
    I know a little about coding.

    I would like it if the new page would open in a new window.

    Thanks for all your great work.
    Much appreciated!