Custom CSS Per Post
I’ve long been a fan of “art directing” posts. That is, to apply unique CSS styling to an individual page of content when the situation calls for it. In the past, I’ve used the Art Direction plugin and I even created a screencast on using it.
As it turns out, there is a major problem with the art direction plugin. Using it with any caching plugin will result in a crazy epic meltdown of your site. Without too much gory detail, in trying to cache my blog CSS-Tricks, I tried all the major caching plugins (DB Cache, WP Super Cache, W3 Total Cache) and ultimately it would trash my WordPress database and serve up white pages. Very not good.
Happy ending
The happy ending is that Frederick Townes from W3 Edge and creator of the W3 Total Cache plugin helped me out by patching the art direction plugin and getting CSS-Tricks cached with W3 Total Cache. I would love to release the updated code, but it’s not my code to release. We managed to get in touch with the original author1, who said he planed to eventually update it but didn’t sound too particularly interested in the patch.
SO, with that extensive backstory, what is a poor fellow to do if they want to apply custom CSS to pages TODAY? Couple ideas, read on.
style-XXXX.css
One of my “WordPress Wishes” was that you could drop an appropriately named CSS file into a theme and it would recognize it and apply itself to the proper post. For example, /art-direction/style-XXXX.css
, where XXXX
is the ID of the post.
A reader named Hassan commented with a cool idea for the functions.php
file:
function artStyle() {
global $post;
if (is_single()) {
$currentID = $post->ID;
$serverfilepath = TEMPLATEPATH.'/art-direction/style-'.$currentID.'.css';
$publicfilepath = get_bloginfo('template_url');
$publicfilepath .= '/art-direction/style-'.$currentID.'.css';
if (file_exists($serverfilepath)) {
echo "<link rel='stylesheet' type='text/css' href='$publicfilepath' media='screen' />"."\n";
}
}
}
add_action('wp_head', 'artStyle');
I tested it out and it works great. To use it, simply create a new folder called “art-direction” in your theme. Then to style any particular Post or Page, just drop a file in that folder named style-XXXX.css
where XXXX
is the ID of the Post or Page. When that Post or Page loads, WordPress will look for a file of that name. If it exists, it will load in in the head section.
Custom Panel
Reader Kerrick Long commented another cool solution. Similar to the Art Direction plugin, this adds an input area below the main content writing area. For the functions.php
file:
//Custom CSS Widget
add_action('admin_menu', 'custom_css_hooks');
add_action('save_post', 'save_custom_css');
add_action('wp_head','insert_custom_css');
function custom_css_hooks() {
add_meta_box('custom_css', 'Custom CSS', 'custom_css_input', 'post', 'normal', 'high');
add_meta_box('custom_css', 'Custom CSS', 'custom_css_input', 'page', 'normal', 'high');
}
function custom_css_input() {
global $post;
echo '<input type="hidden" name="custom_css_noncename" id="custom_css_noncename" value="'.wp_create_nonce('custom-css').'" />';
echo '<textarea name="custom_css" id="custom_css" rows="5" cols="30" style="width:100%;">'.get_post_meta($post->ID,'_custom_css',true).'</textarea>';
}
function save_custom_css($post_id) {
if (!wp_verify_nonce($_POST['custom_css_noncename'], 'custom-css')) return $post_id;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id;
$custom_css = $_POST['custom_css'];
update_post_meta($post_id, '_custom_css', $custom_css);
}
function insert_custom_css() {
if (is_page() || is_single()) {
if (have_posts()) : while (have_posts()) : the_post();
echo '<style type="text/css">'.get_post_meta(get_the_ID(), '_custom_css', true).'</style>';
endwhile; endif;
rewind_posts();
}
}
As written, it’s more limiting than the Art Direction plugin as it is for CSS only rather than “anything” (e.g. JavaScript), although that would be a fairly trivial adjustment to what gets echoed out. The Art Direction plugin also allowed the CSS to be applied in other places the post might be output, for example, archives pages, whereas this does not. But to be honest, I never used that anyway.
And so…
Two pretty sweet and totally function solutions by Digging Into WordPress readers. Awesome. Huge thanks to Hassan and Kerrick! I would also love to see the Art Direction plugin updated as well, if nothing else, because I’m sure people download that plugin every single day from the plugin repository and have caching going on their blogs and end up in the same sore spot I was.
Notes
- 1 Editor’s note: 404 link removed.
30 responses
-
Php is not my thing yet and I am an novice to wordpress but I am reading DIWP the book. The code in your solution is minimal but can you do the same thing by creating a custom post page that uses a specific header which calls the stylesheet?
-
This is awesome, thank you.
I installed Art Direction plugin on my site and used it for a post about a month ago…my site crashed and burned every time I opened it in IE 6 & 7. I had recently added a jQuery nav bar & a few other plugins to my site so it was hard to tie it back to this particular plugin.
Any chance you can simply release the chunk of code that you fixed? I’m not sure what the license is or how much code you modified, but maybe that’s an option.
Again, huge thanks for these alternate options though!
-
Interesting solutions, both of them and they probably can be used in conjunction. Sometimes you just need smaller classes added, sometimes you need longer styles, where a .css file would be cleaner in the end.
-
Would this work? or would they clash?
-
-
Thanks Chris for these. I currently have a custom key in my head that I can use to call a .css I manually upload to the server in the theme’s folder.
The larger question here is how to design an overall theme that can accomodate some posts being art directed. It comes down to making your theme modular in some respects, so that you can swap out a standard post for a blank slate in which to create something unique.
I use an if/then statement to house the default layout, and then if it is in a category of ‘unique’ I have a very simple I simple have the_content and thats it.
-
I personally hate file management, which is why I suggested the Custom CSS box on the page – but either choice is awesome, based on your personal preferences.
Thanks for writing this article, and including my suggestion – it made my day!
-
What’s the difference between the Art Direction plugin and creating Custom Fields to input css into individual posts?
What I’ve done for my portfolio website is run the below code on the
header.php
file and create a custom field relevant to the Custom Field name. It’s quite simple and doesn’t need a plugin to do that.<?php if (is_single()) { $css = get_post_meta($post->ID, 'css', true); if (!empty($css)) { ?> <style type="text/css"> <?php echo $css; ?> </style> <?php } } ?>
-
The second code snippet for Custom CSS does, in fact, use custom fields. Because the custom field’s name begins with and underscore, it’s hidden from the custom fields dropdown – which means we need to create an input on the post/page edit screen for it.
In my opinion, it’s easier to find the box labeled “Custom CSS” and type in it, than it is to type “custom_css” into a custom field key, and then fill out its value.
-
I’m in agreement with it being easier to find the labeled “Custom CSS” field and simply enter the relevant value. But having avoided naming a Custom Field that starts with a ( _ ) underscore has kept my Custom Fields on the drop down menu. Which is not laborish to say after you’ve set up the backend work.
But that is something I’m looking forward to simplify on my current portfolio theme.
-
-
-
Thanks, Chris. Add me to the list of folks that would love to see the Art Direction plugin updated. I’ve always wanted to use it, but was too afraid of a DB meltdown that I’m unable as of yet to fix.
Props to Hassan as well, for a clean fix.
-
Isn’t this plugin suitable for this task? Custom CSS and JS. Also found this one: Easy JS/CSS and there’s probably others in WP Repository.
The way I do it now is putting these posts in a separate (hidden) category and call this in either
wp_head
orwp_footer
withif (in_category('hidden-cat-name')) {
// include whatever
}
-
PS Since the Art Direction plugin is GPL anyway, why don’t your or Frederick just fork it as ‘Art Direction – Cache Enhanced’ and be done with it ;) You’re helping countless others who have no idea this solution exists otherwise.
-
Is there a way to extend Hassan’s version up to categories and possibly tags?
-
I haven’t heard anything from you Chris and I appreciated Fredrick patching the plugin, however it was found that his patch also caused a few headaches for other plugins.
I’ll be updating the plugin this week. Thanks for the heads up. Next time you need any help, just send me a note yourself and I’ll try to more swiftly patch it up.
-
Really useful as usual Chris! I love this kind of solutions, and I believe that the less plugins the better. Personally, I have gotten away with just using
body_class();
and then using CSS hierarchy. Also, David Walsh posted a great “extension” of this idea in one of his latest posts. -
Great Job guys .. an awesome way of creating more style ..
-
I was wondering if this could be used to make a custom homepage for a wordpress site. I am designing a site where a client wants a wordpress but wants his homepage to look like a normal site not a blog.
-
I was wondering if anyone out there had seen this plugin, Per-Post CSS. It actually works really well.. Unfortunately since no work has been done on it for a few years it causes some small w3c errors, but I am sure something someone can easily fix.
If there is anyone out there that can take this code and make it work without the errors in w3c that would be awesome. Well at least for me. I posted here because it seems like a decent group of people wanting to solve a common condition. I just hope I did not read it wrong.
Editor’s note: 404 link removed.
-
Thanks, as always, Chris… I’ve got the latest update of Art Direction on my site and, for some reason, I’m getting those blank screens… I’ll try your solutions. Thanks for putting the time in.
-
Nice solutions, Chris. I’m trying out the first one myself.
I was scratching my head for a while, though, wondering why it wasn’t working until I realized there’s a small bug in the code for functions.php (single quote missing):
type=text/css'
-
I have an update to the function if you are using a child theme.
The important parts being how you get the child theme directory absolute server path and url.function artStyle() { global $post; $currentID = $post->ID; $serverfilepath = get_stylesheet_directory().'/art-direction/style-'.$currentID.'.css'; $publicfilepath = get_bloginfo('stylesheet_directory'); $publicfilepath .= '/art-direction/style-'.$currentID.'.css'; if (file_exists($serverfilepath)) { echo "<link rel='stylesheet' type='text/css' href='$publicfilepath' media='screen' />"."n"; } } add_action('wp_head', 'artStyle');