On a recent project I noticed that I was duplicating a bunch of CSS code. Because this duplication is evil, and would keep me up at night, I decided to do something about it.
I quickly noticed that all the code that was being duplicated depended on one magic parameter, lets call it foo. If only, I thought, I could parameterize the value of foo, I'd be all set. But you simply can't do that in CSS (gosh I dislike languages that don't give you basic abstraction capabilities, like variables).
But I do have a language handy which does do what I want - JSP. JSP, after all, does exactly what I want for HTML files, so why can't I apply that to CSS. Of course I can. And did. Here's the recipe.
First, start with your separate files, like:
/* basic_look.css */ body { background-image: url('images/basic_bg.gif'); } /* fancy_look.css */ body { background-image: url('images/fancy_bg.gif'); }
Next, put them in a single file, and make use of your token:
/* look.css.jsp <-- notice the .jsp here */ body { background-image: url('images/${foo}_bg.gif'); }
At this point, you might think the final step is to update the document that uses this as so:
<!-- Old Approach --> <link rel="StyleSheet" href="basic_look.css" type="text/css"/> <link rel="StyleSheet" href="fancy_look.css" type="text/css"/>
to:
<!-- New Approach --> <link rel="StyleSheet" href="look.css.jsp" type="text/css"/>
But if you did just that, you would actually be wrong. (Hence the need to write up this howto, so 2 years from now when I want to recall how to do this, I can search my blog and find out how again.)
The problem is that a .jsp document, by default, produces a header that says the content type is text/html. This is usually a good thing. Except when it's not. And now it's not.
So you need to make the above change and change your .css.jsp file to:
<%@ page language="java" contentType="text/css" %> /* look.css.jsp <-- notice the .jsp here */ body { background-image: url('images/${foo}_bg.gif'); }
Now you're all set. Whew, with that taken care of I should have no problem sleeping at night.
You might also consider using SiteMesh decorators to help with this kind of stuff. One advantage there is that it's pluggable into just about any MVC framework.
ReplyDeletePS - I hate this Blogger signin crap, why they can't cookie this stuff correctly is beyond me. C'mon google!
Nice How-To!!
ReplyDelete