posted: April 14th, 2007 · by: Sven
Skimming through the PHP source article and code I thought that something similar could be done as a Rails plugin pretty easily and elegantly. I couldn’t resist, sat down and started coding away … so here are my results.
What does it?
Basically, what the plugin does is:
- compact this bundle by removing whitespace, comments and the like
- cache the bundle by using Rails default page caching mechanism
- create an “accesspoint” to the bundle by adding an appropriate route
How to access the bundles?
Rakaz proposes the following syntax in his article to define a bundles contents and access them through an URL:
… which I think is ok, but can be done more concise - we don’t really need the repetition of
.css because we wouldn’t allow to combine CSS files with JS or other filetypes anyways.
It makes sense though to append the information that we’re dealing with CSS files here as a regular file extension (
.css) because this helps with webserver configurations and the like. So this is preferable over:
What will be bundled?
Now, if you access the URL above and there are the files
three.css in your
public/stylesheets directory, the plugin will combine them into a single bundle file, compress them and page-cache them for future requests in the
If there’s a subdirectory
one (instead of a file
one.css), a recursive glob will be performed and and all CSS files in the subdirectory (and recursively all of its subdirectories) will be collected and merged into the bundle as well. This makes sense when you have a large number of separate files: you can access them through their directory name then.
If there’s no correspondent file
one.css or directory
one at all this part silently will be ignored.
How does the compression work?
It’s not really compressed, but compacted. I haven’t build in any gzip/deflate compression because I can use Apache’s mod_deflate for this task. This could be added easily though I guess.
Instead the plugin uses:
- some code from Scott Becker’s AssetPackager (which by the way does something similar like this plugin but takes a different approach)
How to install?
You can install this plugin simply by using Rails script/plugin installer. Standing in your Rails root directory do:
script/plugin install http://svn.artweb-design.de/stuff/rails/bundled_assets/
Also, up to now you’ll have to add a route to your routes setup manually. Therefor edit your config/routes.rb file and add the following line (somewhere above Rails’ default routes):
map.connect 'bundles/:names.:ext', :controller => 'assets_bundle', :action => 'fetch', :ext => /css|js/, :names => /[^.]*
How to use?
After you’ve successfully installed this stuff (do not forget to restart your server) you can use it in your templates (again, do not forget to invalidate your page caches if necessary). E.g., the layout template of this blog contains the following lines:
Possible improvements? Problems?
Besides integrating basic gzip output compression the plugin could use some configuration options such as whether or not subdirectory contents should be bundled, whether or not the code should be compacted (and how).
Also, there’s currently no solution for a possible problem with relative image URLs in CSS files that are bundled from within subdirectories (and this way “transferred” to upperlevel directories). Using absolute URLs should work in this case though.
What do you think?