Dynamic Stylesheet

Dynamic Stylesheets are more PHP than CSS but CSS is required. It's just nice to know you can mix the two.

This has been something that has plagued me for a while now: dynamic stylesheets. What is the purpose? Well. sometimes it would just be nice if you could create IDs and classes on the fly, and not have to update the stylesheet every single time you do something.

As an example, say you want all the Pages on your blog to look different, so you have the body tag dynamically generate an ID for every page, using the pagename. But the stylesheet – well… every time you want some kind of different layout, you have to manually edit the stylesheet. Wouldn’t it be nice if you could just have it happen when you created the Page?

Now, I haven’t done anything quite that dramatic yet – but I did recently have a client who used WordPress as a CMS. The dynamic stylesheet idea was perfect for this, because we had some odd navigation, and wanted to reflect the changes when additional parent and child pages were created. meaning, if you were on a child page, we wanted the main parent page link to remain highlighted. However, we didn’t want to have to go in every single time a new page was created and add all of this information to the stylesheet – we just wanted it in “auto.”

Now, there are TONS of dynamic stylesheet tutorials out there, and there are so many reasons to use it. But really, what it comes down to is a single point: you save the stylesheet as a PHP file and you must be sure to add header('Content-type: text/css'); at the top of said file. Everything else is pretty much the same – save all of your colors, fonts, etc. are now dynamically generated by replacing them with variables.

I’ve done dynamic stylesheets before – but the trick was with WordPress. Personally, I hate having style information in the document head. I like to keep my files separate. Yes, I’m so picky that I even will edit my code so when you “view source” on a site, things are lined up and spaced properly, every time it’s possible for me to do so. (I AM that anal.) I haven’t figured out why yet – but you can create a dynamic stylesheet for WordPress BUT the clincher is that it’ll only work if you actually output the code in the head section of the file. You can’t just link to the stylesheet and have it change on the fly. (One day, I’ll figure out why, and update this – but so far I haven’t been able to!) You certainly can do an external stylesheet, you just need to be sure to globalize the data you want to pass to the file. For example, if you want to use post or Page slugs, then add global $post, $page; at the top, under the header call. Then later, you can call them in buy using $post->post_name; to get the post name for setting a class or ID.

So, it’s something I’ve had to put up with. But then again, because it’s “on the fly” it’s not a ton of code – so it’s acceptable.

So I’m going to use the aforementioned site to explain how this is done. Of course, you can use any method you like for any purpose you like, but this is pretty simple, and illustrates the point. We used “Son of Suckerfish” (actually, the WordPress plugin for it – although a colleague tells me that SOS isn’t great if you’ve got huge dropdowns, which I agree with. If you have HUGE lists, then go with his – they’ve much better! SOS is for simple dropdowns. Ah hell, while I’m here, I might as well plug brothercake too – theirs are nice as well!) for the dropdown menus, and the dynamic stylesheet was an addition/override to the default, so we could really customize how things were working.

So, like I said, we first need to create the function that’ll make this happen. So open up your functions.php file (within your theme – if you don’t have one, then you can create one). You just want to add this little snippet of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function get_pagename() {
    global $post;
    if(is_home() || is_front_page()) {
        $title = "index";
    }
    
    if(is_page()) {
        if($post->post_parent) $id = $post->post_parent; 
        else $id = $post->ID;
        
        $info = get_post($id);
        $title = $info->post_name;
    }

    if(is_category()) {
        $catid = get_query_var('cat');
        $cat = &get_category($catid);
        $parent = get_category_parents($catid, FALSE, ',');
        $catlist = explode(',',$parent);
        $toplevelname = $catlist[0]; //top level nicename
        $id = get_cat_id($toplevelname);
        $info = &get_category($id);
        $title = $info->slug;
    }

    return $title;
}

Now, all this does is look at the page you’re on (be it a Page or a post, or even just a category) and threads through it to find the parent. If you’re on a post, it’ll find that posts’ category parent; if you’re on a Page it’ll look for the top-level parent page (so even if your on a subpage of a subpage, it’ll still find the topmost level parent.) Works for categories, as well as subcategories of subcategories…I could go on. It finds that topmost parent, and outputs the slug for that parent, and echoes it out. Of course, if you’re on the index page, it’ll output the ID as “index” – so you’re good no matter what. You’ll see why this is important in a moment.

Now, you open up your header.php file, and look for the <body> tag. You want to add the function to it, so change it to look like so:

<body id="<?php echo bb_get_pagename(); ?>">

So now, it’ll output the id of the page you’re on, using the topmost level of whatever section your on as the ID name. Cool, eh? Go ahead, try it out – view your source code, and you’ll see everywhere you go, the topmost level is named as that page ID. That, in itself, is very useful. But we’ll take it a step further.

Now, let’s do our dynamic stylesheet. Back to the functions.php file. Below the finction you just created, you want to add this:

<?php
function dynamic_stylesheet() {
// start by forcing recognition of default stuff
global $post, $title;
// now set the pagename as an ID
$page = '#' . $title;
// now let's get stylin' ?>

<style type="text/css">
<?php if(is_page()) {
echo $page; ?> #suckerfishnav li.current_page_item a, <?php echo $page; ?> #suckerfishnav li.current_page_ancestor a
<?php } else if(is_category()) {
echo $page; ?> #suckerfishnav li.cat-item-<?php echo $id; ?> a
<?php } ?> { color:#FFA903; }

<?php if(is_page()) {
echo $page; ?> #suckerfishnav li.current_page_item li a, <?php echo $page; ?> #suckerfishnav li.current_page_ancestor li a
<?php } else if(is_category()) {
echo $page; ?> #suckerfishnav li.cat-item-<?php echo $id; ?> ul.children a
<?php } ?> { color:#FFF; }
</style>
<?php }

add_action('wp_head', 'bb_dynamic_ss');
?>

And that’s all there is to it. If you do all this, and view your source code, you’ll see that 1) the “body” tag now ID’s itself by whatever parent it’s associated with, and 2) just above it (or wherever you have your <?php wp_head(); ?> tag located – I recommend just before the closing HTML tag) you’ll see your styles for that page – should only be two lines.

Hope it helps someone!

Comments

  • […] most interesting part of the project (aside from figuring out a cool dynamic stylesheet in getting the menus to function exactly how we wanted) was working with WP e-Commerce. These guys […]

  • Ryan says:

    Thanks for mentioning our plugin :)

    • Shelly says:

      Well, when something’s good and you use it, you shouldn’t keep it all to yourself ;) Thanks for swinging by to comment :)

  • […] help a lot of you also take a look at an old tutorial I have here on the site: Dynamic Stylesheets. It’s not necessary, but it sure does make things a whole hell of a lot easier. So […]

  • Have your say: