How to: Provide Different Color Schemes for Your WordPress Theme

We’ve covered how to add a new color scheme to Twenty Eleven by child theming it in a previous post, and today I’ll show you how to create color schemes for your own theme, and have other developers take advantage of that to add their own new colors by child theming yours.

We’ll be using a technique similar to what Twenty Eleven does. We’ll make sure that the stylesheet is split and that a new CSS file can add and override several rules from the main one. This is done so that the main stylesheet is never needed to make any color changes, thus making child theming possible. We’ll then create a neat file structure to hold the color scheme theme image files, stylesheets and preview images, and finally attach them all to create the Theme Options page in the admin panel.

As an example I’ll be using a free theme called San Fran which offers three different color schemes to pick from, which an option to create your own. San Fran is licensed under the GPL v2, so feel free to use and reuse any of it’s assets. San Fran is not yet available, but will be in the WordPress.org Themes Directory as soon as it passes the review. You can get an early version of San Fran right here.

San Fran Theme Options

Understanding the Files Structure

It’s really up to you on how you lay out your files, but keep in mind that if you’re creating a theme that is supposed to act like a child theme in the future, you should try and keep your files and folders organized, since other developers will have to find their way through. Don’t forget about commenting your code too, which is very essential to WordPress themes.

San Fran File Structure

Basically San Fran comes with an additional directory called colors with three different folders inside, each one representing a different color scheme. There are (currently) three files in each of those folders — a stylesheet, an image used in the theme and a preview image for the Theme Options page. Of course your files will be different depending on what kind of theme you’re working on.

If you open on any of those color stylesheets you’ll notice that they’re quite simple. They don’t contain too many rules, mostly colors and typography, while most of the elements and their styles are defined in the theme’s main stylesheet in it’s root directory. San Fran puts additional CSS files (the 960 grid and a reset.css) in the css directory. They’re essential to the theme’s structure, so there’s no need to give a way to override them.

The Theme’s Functions

The functions.php file is quite big and you might have noticed that we’ve given it an object-oriented approach at WordPress themes. This is one of the ways to organize the functions file. Another one is the linear prefixed functions approach (like Twenty Eleven) where every function is globally available. There’s no right or wrong way, they both have pros and cons.

Keep in mind that San_Fran is a class, and a global $sanfran object is created at the very bottom of the file during the after_theme_setup action, so that’s when the class constructor is fired. We won’t got through all the class methods in this tutorial since we’re limited to color schemes, but we will cover a little bit of options, admin settings and settings fields and sections.

Saving and Loading the Theme Options

This part is not about the theme options page, it’s rather about the two arrays that hold the user options and default options, as well as the two class methods used to save and load those options. You’ll notice that the San_Fran class defines two instance variables called $options and $defaults. The $defaults array is initialized in the class constructor, quite self-explanatory. The $options array is managed through two methods called load_options and update_options.

function load_options(){
	$this->options = (array) get_option( 'sanfran-options' );
	$this->options = array_merge( $this->defaults, $this->options );
}

The load_options method grabs the options from the database and uses array_merge to merge the array with the default options array. This is done for when there’s no entry in the database for such an option, meaning the options array will fall back to the defaults.

function update_options() {
	return update_option( 'sanfran-options', $this->options );
}

The update_options method is even simpler, it grabs the options array and updates the database entry.

So now that the two methods are defined, you can use the load_options method in the class constructor which will ensure that the $options instance variable is populated with data, whether it’s user-set data or the ones grabbed from the $defaults instance variable. So in your class constructor:

// Load options (calls get_option())
$this->load_options();

Validating Theme Options

You should never miss this step as it’s quite important to provide the best user experience. It’s really up to you on how to actually validate the theme options, but make sure that whatever the user types in the Theme Options page, doesn’t have to break your whole website. Of course this doesn’t count for Custom CSS or scripts fields.

Here’s the validate_options method for San Fran:

function validate_options($options) {
	// Theme options.
	$options['color-scheme'] = array_key_exists( $options['color-scheme'], $this->get_valid_color_schemes() ) ? $options['color-scheme'] : 'default';
	$options['footer-note'] = trim( strip_tags( $options['footer-note'], '<a><b><strong><em><ol><li><div><span>' ) );
	$options['custom-css'] = trim( strip_tags( $options['custom-css'] ) );

	return $options;
}

You don’t have to get into all the details at this stage. It’s good enough if you understand that the method is run prior to writing the new Theme Options into the database, where the $options array is passed in as an argument. Rest is up to you, just make sure you return the same array with the changes you have made.

Also note the usage of the get_valid_color_schemes method which i’ll talk about very soon. The validate method itself is called by the WordPress Settings API, which brings us to the next step — admin settings.

Registering Admin Settings and Settings Fields

The San Fran theme has three settings fields — color scheme, footer note and custom CSS. We’ve seen the validate_options method above so you should have a general idea of what each field can contain. I wrapped all the settings into a method called register_admin_settings which is called during admin_init (see constructor) and here’s how it looks:

function register_admin_settings() {
	register_setting( 'sanfran-options', 'sanfran-options', array( &$this, 'validate_options' ) );

	// Settings fields and sections
	add_settings_section( 'section_general', __( 'General Settings', 'sanfran' ), array( &$this, 'section_general' ), 'sanfran-options' );
	add_settings_field( 'color-scheme', __( 'Color Scheme', 'sanfran' ), array( &$this, 'setting_color_scheme' ), 'sanfran-options', 'section_general' );
	add_settings_field( 'footer-note', __( 'Footer Note', 'sanfran' ), array( &$this, 'setting_footer_note' ), 'sanfran-options', 'section_general' );
	add_settings_field( 'custom-css', __( 'Custom CSS', 'sanfran' ), array( &$this, 'setting_custom_css' ), 'sanfran-options', 'section_general' );

	do_action( 'sanfran_admin_settings' );
}

One setting, one section and three fields, simple as that. If you’ve no idea what the code above is doing, please consult the Settings API section in the Codex. Keep in mind that this post is about color schemes, not settings in general. So the color scheme setting is handled by a method called setting_color_scheme, and also note the call to do_action which allows child themes and plugins to add their own settings fields and sections to our Theme Options page. We’ll talk about the setting_color_scheme method soon, but not about the others.

The Theme Options page itself is rendered by a method called theme_options which uses some neat HTML to wrap the options, and calls to the settings_fields and do_settings_sections to render the actual options. We’re not covering on how the Theme Options page got into the admin menu. Again, this post is about color schemes, not the Settings API.

So by now we’ve covered the handling of theme options. Your class should be able to save and load options, validate the options and generate the Theme Options page with the descriptions and controls.

The Color Schemes and Scripts

We’ve used this method before which returns an array of available color schemes and here’s how it looks:

function get_valid_color_schemes() {
	$color_schemes = array(
		'default' => array(
			'name' => __( 'Default', 'sanfran' ),
			'preview' => get_template_directory_uri() . '/colors/default/preview.png'
		),
		'darker' => array(
			'name' => __( 'Darker', 'sanfran' ),
			'preview' => get_template_directory_uri() . '/colors/darker/preview.png'
		),
		'greener' => array(
			'name' => __( 'Greener', 'sanfran' ),
			'preview' => get_template_directory_uri() . '/colors/greener/preview.png'
		)
	);

	return apply_filters( 'sanfran_color_schemes', $color_schemes );
}

As you can see, the available color schemes reside in an associative array, the key is the “value” of the color scheme that will live in the theme options entry in the database. The name is what appears in the Theme Options page together with the preview image. Note the usage of get_template_directory_uri and not get_stylesheet_directory_uri, since we don’t want our child themes to override existing color schemes, but rather add their own through the filter applied at the end of the method.

The actual stylesheets are done a little bit differently. We don’t refer to the stylesheets in the color schemes array, since we want to be able to include more than one stylesheet, no stylesheet at all or perhaps a javascript file, right? Here’s the method that’s called when printing the site’s scripts and styles:

function color_scheme_scripts() {
	if ( isset( $this->options['color-scheme'] ) ) {
		if ( $this->options['color-scheme'] == 'default' ) {
			wp_enqueue_style( 'sanfran-default', get_template_directory_uri() . '/colors/default/default.css', array(), null );
		} elseif ( $this->options['color-scheme'] == 'darker' ) {
			wp_enqueue_style( 'sanfran-darker', get_template_directory_uri() . '/colors/darker/darker.css', array(), null );
		} elseif ( $this->options['color-scheme'] == 'greener' ) {
			wp_enqueue_style( 'sanfran-greener', get_template_directory_uri() . '/colors/greener/greener.css', array(), null );
		}

		do_action( 'sanfran_enqueue_color_scheme', $this->options['color-scheme'] );
	} else {
		wp_enqueue_style( 'sanfran-default', get_template_directory_uri() . '/colors/default/default.css', array(), null );
	}
}

Basically it does a check for the currently selected color scheme and enqueues the necessary stylesheet. There’s a fallback to the default color stylesheet if no color scheme has been selected (wondering how this may ever happen, but okay). There’s also a do_action call which ensures that child themes and plugins can hook into this method and link their own stylesheets and other assets if necessary, passing in the selected color scheme.

The method itself is called during the wp_enqueue_scripts action triggered by wp_head. Here’s what you may have noticed in the class constructor:

add_action( 'wp_enqueue_scripts', array( &$this, 'color_scheme_scripts' ) );

So just to make sure you’re still with me — in the child theme, instead of hooking to wp_head directly, you can easily hook to the sanfran_enqueue_color_scheme action and accept an argument, which is the chosen color scheme. You run an if expression on that color scheme to determine whether it’s yours and enqueue the scripts and styles needed to run the new color scheme.

The Color Scheme Setting

There’s one simple part remaining which I skipped in the steps above. Remember when you registered the admin sections and settings field? One of the settings fields referenced a method called setting_color_scheme, which is the form element displayed in your Theme Options page.

It’s totally up to you on how to structure the Theme Options page, but here’s something I quickly drafted for San Fran:

function setting_color_scheme() {
?>
	<?php
		$color_schemes = $this->get_valid_color_schemes();
		foreach ( $color_schemes as $value => $scheme ):
	?>
	<div class="color-scheme-item" style="float: left; margin-right: 14px; margin-bottom: 18px;">
		<input <?php checked( $value == $this->options['color-scheme'] ); ?> type="radio" name="sanfran-options[color-scheme]" id="sanfran-color-scheme-<?php echo $value; ?>" value="<?php echo $value; ?>" />
		<label for="sanfran-color-scheme-<?php echo $value; ?>" style="margin-top: 4px; float: left; clear: both;">
			<img src="<?php echo $scheme['preview']; ?>" /><br />
			<span class="description" style="margin-top: 8px; float: left;"><?php echo $scheme['name']; ?></span>
		</label>
	</div>
	<?php
		endforeach;
	?>
	<br class="clear" />
	<span class="description"><?php _e( 'Browse to your home page to see the new color scheme in action.', 'sanfran' ); ?></span>
	<?php
}

It’s quite simple to understand actually. All I do is a loop through the available color schemes and print out radio buttons using the array’s keys as the radio values. I also print out labels containing the color scheme names and the preview image of course.

There’s quite some CSS mess here, and you’ll have that too when experimenting with your own color schemes. Ultimately, you should clean up that mess and include a proper style sheet to your Theme Options page that contains all the styling rules for your form elements.

Recap, this method is called when rendering the settings fields and is attached to your setting when calling add_settings_field during admin_init. Make sure you got the name attribute of your radio buttons right, since they’ll be used to validate your options and finally save them to the database.

Conclusion

So basically this is all there is to it. While not being a post about the Settings API, most of the code is actually dedicated to dealing with the theme settings, while only three methods are solely dedicated to the color schemes. The first two methods (get_valid_color_schemes and color_scheme_scripts) are extensible via actions and filters, just like Twenty Eleven is, to make sure child themes and plugins can benefit from your code by adding their own color schemes.

Color Scheme Default

Color Scheme Darker

Color Scheme Greener

You should have noticed by now that there’s no code snippets in this post which you can copy-paste into your own and get things working. It’s all about getting it right as a whole, which is why I have attached the current (development) version of the San Fran theme. There’s no guarantee that it will not be changed in the future, although the concept if color schemes remains the same. Feel free to inspect the code, which is well commented and GPL licensed to find your way around.

Let us know if you have any questions and comments, we’ll be glad to help you out. Also share if you know a better technique of implementing color schemes to your WordPress themes, and of course don’t forget to subscribe to our RSS feed.