Categories
Posts

Database Powered CSS in WordPress Themes

A popular ability in WordPress themes is to add custom CSS driven by options. This brings up a common question, how should the theme inject custom CSS? I’ll outline three different approaches on how to do this. These aren’t new, many people have written about these; forums, blog posts, email lists and IRC. I’m still seeing questions about this though, so I wanted to address this specific question with specific solutions.

For the purposes of code examples I’ll assume that you have an option called my_background_color and that you want to do something like this:

[sourcecode lang=”css”]
body {
background-color: <?php echo $theme_opt[‘my_background_color’]; ?>
}
[/sourcecode]

We’ll start with the simplest method.

header.php

Most themes have a header.php file that contains template code for the top of the HTML output. This makes it easy to add custom CSS with options, just echo it out inside the HEAD section of the HTML:

[sourcecode lang=”html”]
<style type=’text/css’>
body {
background-color: <?php echo $theme_opt[‘my_background_color’]; ?>
}
</style>
[/sourcecode]

The advantages to this approach is that it’s very simple, you already have a header.php so adding a few more lines doesn’t take much work. The disadvantage is that this solution isn’t very flexible, if you have complex rules about when and how to include the CSS then your header.php file gets a lot extra “stuff” that may not need for every page.

If your needs are simple then this works great. If not, I suggest using either wp_head or parse_request.

wp_head

Each theme calls a WordPress action at the end of the HTML HEAD section – wp_head – that can be used to include the custom CSS:

[sourcecode lang=”php”]
<?php
add_action( ‘wp_head’, ‘my_custom_css_hook’ );
function my_custom_css_hook( ) {
# get theme options
?>

<style type=’text/css’>
body {
background-color: <?php echo $theme_opt[‘my_background_color’]; ?>
}
</style>

<?php
}
[/sourcecode]

The only real difference between this approach and the previous one is that it’s less clutter in header.php. Instead of having all that code in header.php it can be moved out to a separate file and WordPress will include it at runtime whenever the wp_head action fires.

parse_request

WordPress can provide your theme with custom URLs, these can turn around and serve up what ever you want, including CSS. This technique takes a little bit more work, but provides the maximum degree of flexibility. There are a couple steps to this one, first what you’ll need to have in header.php:

[sourcecode lang=”html”]
<link rel=’stylesheet’ type=’text/css’ href="<?php bloginfo( ‘url’ ); ?>/?my-custom-content=css" />
[/sourcecode]

The my-custom-content=css just needs to be something unique to your theme so that it doesn’t conflict with plugins that might be using parse_request as well.

Next we need to tell WordPress how we want to handle this request:

[sourcecode lang=”php”]
add_action( ‘parse_request’, ‘my_custom_wp_request’ );
function my_custom_wp_request( $wp ) {
if (
!empty( $_GET[‘my-custom-content’] )
&& $_GET[‘my-custom-content’] == ‘css’
) {
# get theme options
header( ‘Content-Type: text/css’ );
?>

body {
background-color: <?php echo $theme_opt[‘my_background_color’]; ?>
}

<?php
exit;
}
}
[/sourcecode]

A few things in there that I want to point out. Pay attention to line 8, this tells the browser what sort of content we are sending back. In this case it was CSS, but it could have been JavaScript or anything else. Also note that I didn’t add any cache related headers, it’s worth reading up on cache control in HTTP headers so that you know how that works. Line 16 is also important, we don’t want WordPress attempting to do any further processing after we return the CSS so the right thing to do is exit as soon as possible.

And if you wanted to keep the CSS in a separate file ( custom-css.php for our example ) that looked more like a normal CSS file then the my_custom_wp_request function could look like:

[sourcecode lang=”php”]
function my_custom_wp_request( $wp ) {
if (
!empty( $_GET[‘my-custom-content’] )
&& $_GET[‘my-custom-content’] == ‘css’
) {
# get theme options
header( ‘Content-Type: text/css’ );
require dirname( __FILE__ ) . ‘/custom-css.php’;
exit;
}
}
[/sourcecode]

allowing your custom-css.php to look like:

[sourcecode lang=”CSS”]
body {
background-color: <?php echo $theme_opt[‘my_background_color’]; ?>
}
[/sourcecode]

basically just enough PHP to fill in the option blanks, other wise a normal looking CSS file. I rather like this approach, it provides a nice degree of separation and control.

Conclusion

Now you have three methods for including database powered CSS in your WordPress theme. I like using parse_request with the CSS in a separate file ( the last example ), for a little bit of extra work you get lots of flexibility and a nice layer of separation that makes managing the CSS portion easier.

Having any tips on how to improve on this? Leave a comment below!