This is where Adam Spooner writes.

Managing CSS and JS in ExpressionEngine

Posted on

ExpressionEngine, hereafter EE(ExpressionEngine), has great built-in support for managing style sheets and JavaScript. Here’s one simple way to manage your style sheets and JavaScript files with cache-busting and gzip compression using EE(ExpressionEngine)’s templating system.

There’s one prerequisite for managing styles and scripts using the following method: the LG .htaccess Generator. It’s possible to use a different approach, but this method assumes you’re using Mr. Graham’s extension.

First, if you haven’t already, enable gzip compression from within EE(ExpressionEngine)’s control panel. Go to Admin > System Preferences > Output and Debugging Preferences and select “Yes” under “Enable GZIP Output?” Click “Update” to save your settings.

Next, create a new template group for your style sheets. I generally name mine “styles”, but name yours whatever you’d like. Don’t duplicate a group. Click “Submit” to create the group. Within this new group, create a few templates with a type of “CSS Stylesheet”. I generally create a style sheet template for each logical group of styles: a style reset, some typographic styles, default styles, some hacks, etc. Put corresponding styles in each of these templates. I save all templates as files and use EE(ExpressionEngine)’s built-in template revision system. You should see a checkbox with the label “Save Template as File” just above the “Update” and “Update and Finished” buttons on the template editing page. You’ll need to allow templates to be saved as files if you don’t. Go to Templates > Global Template Preferences > and select “Yes” under “Allow Templates to be Saved as Files?” While you’re there, select “Yes” under “Save Template Revisions”. Click “Update” to save your settings. This is simply an added safety net since you’re using some sort of version control for your site, right? Right.

Next, repeat the same steps for your JavaScript files. I typically name the group holding JavaScipt files “scripts”. Each of the templates should have the type “JavaScript”. I generally store classes and frameworks (jQuery, Prototype, etc.) in separate templates with each class getting its own template.

At this point you should have two template groups: one holding a few style sheets and an index and another holding a few JavaScript files and an index (“index” is automatically created when you create a template group).

Being kind to your server means you should serve only one style sheet and one JavaScript file per page load, ostensibly. And Server Side Includes—or SSIs—allow this method to be robust and kind to our servers. SSIs are called embeds in EE(ExpressionEngine) lingo.

So, we’ll use each group’s index file to serve a single file per type. Open your style sheet group’s index file and add an embed for each of the templates in your group (minus the index, of course). Here’s my style index as a reference:


Repeat the same process for your JavaScript group’s index file. Remember, the order of the embeds is important.

We need to set the content type for these index files so the browser interprets them correctly. Go to Templates > Template Preferences Manager. In the first section, select your style template group name under “Template Groups” and “index” from the list of templates. In the second section, select “CSS Stylesheet” under “Type”. Click “Update” to save your settings. Repeat the same steps for your JavaScript group’s index file, selecting “JavaScript” as its type. Don’t forget to click “Update” to save your settings.

At this point, you should be able to visit http://yourdomain/styles/ and see a single style sheet containing the files you specified in your style sheet group’s index. The same goes for your JavaScript group.

There’s a final step to make this system nearly perfect: a cache-busting system. You’re caching requests for media files on your server, right? Read Yahoo’s Best Practices for Speeding Up Your Web Site if you’re not sure what I’m talking about. So, you’ll need a way to bust the cache when you make changes to your styles and scripts after you’ve enabled caching on your server. To do this, you need to create two global template variables: one for styles and one for scripts. Go to Templates > Global Variables and “Create a New Global Variable”. Name the variable something memorable. I generally name mine CSS_VERSION and JS_VERSION. The “Variable Content” should be something that’s easy to increment. I use a three digit version number, 1.0.0. You can use whatever you’d like, but be sure to keep it simple. Also, do not input any whitespace (spaces, tabs, or line breaks). Click “Submit” to save each global variable. These global variables will need to be incremented anytime you make changes to their corresponding files. So, you’ll need to change the version number(s) if you add or change a style or piece of JavaScript. The actual number is irrelevant. Incrementing makes sense (for our linear view of time) though.

Finally, we need to add a link and script tag to our document’s head. They should look similar to this (“»” denotes a continuation on the same line):

<link rel="stylesheet" »
      href="/styles/?v={CSS_VERSION}" »
      type="text/css" media="screen" »
<script src="/scripts/?v={JS_VERSION}" »
      type="text/javascript" »

Your mileage may vary.

You’ll notice after each path is a GET variable v. This is the cache-busting variable. The v= isn’t necessary. You could strip it down to just ?{CSS_VERSION}, and it would work fine. You’re probably thinking, “Why not just put the version number inline? Why store it in a global variable?” You could definitely place it inline and everything would work as described. I find storing these version numbers in global variables to be cleaner.

One final note: This method isn’t tied specifically to ExpressionEngine. It should work in any content management system. The nomenclature and syntax will be the only differences.

So, there you have it: a robust, cache-bust-able, single-serving-file method for managing style sheets and JavaScript files in ExpressionEngine. The only ingredient we’re missing to make it perfect is compression/minification, but this system should be robust enough for the majority of sites.