Sharing CSS between Rails and PHP
Many web sites are built using a variety of web applications, using different web frameworks. These sub sites share the same branding and ought to re-use the same CSS and images. How do you re-use these files within your Rails application, without the maintenance overhead of copying and pasting the code into each new application?
I'm currently working on a project which is partly implemented in PHP, partly in WordPress, and partly in Ruby on Rails. There are some Merb and Sinatra applications waiting in the wings, and they all need to share the same layout and branding.
The Problem
Copying and pasting the CSS into each of these projects would clearly cause maintenance difficulties. The CSS used on each project would quickly diverge, causing inconsistencies in the design of each section of the site.
It seems as though all the applications have to share the same CSS files. When your applications are stored in separate directories and are served by different web servers, how do you go about sharing them?
We concluded that we'd serve the CSS and images from /assets
when running in production mode on the live server. Apache was running the PHP site, so it would have been easy to create a new top level assets
directory in the PHP project and serve all the content from there.
There were two problems with this approach:
- The PHP developers might want to make a layout change to their HTML and update the CSS accordingly, breaking the layout of all the other applications that used the CSS. This would be an easy mistake to make as there would be no hint that their changes would affect all the other applications.
- We don't develop the Rails applications under Apache, so
/assets
wouldn't be available to the Rails team during development.
The Solution
We decided to fix the first problem by creating a new project for the CSS and images that define the layout and brand. We then configured Apache to serve these files from /assets
:
<Directory /var/apps/assets/current/public>
Order allow,deny
Allow from all
</Directory>
Alias /assets /var/apps/assets/current/public
This took care of the PHP side of things, as /assets
would be available both in development, and in production (the developers just need to symlink the public
directory to their local copy of the source code).
The Rails team were no better off at this point, as they develop using a local copy of Mongrel running on port 3000. In production the CSS will be available under /assets
, so we need to serve it from http://localhost:3000/assets
during development.
You can set this up by creating a symlink to a local copy of the assets
. We added this code to config/environments/development.rb
:
def symlink_to_shared_assets
assets_path = File.join(RAILS_ROOT, "..", "assets", "public")
if ! File.exist?(assets_path)
$stderr.write("ERROR: can't find the assets module\n")
exit 1
end
if ! File.exist?("public/assets")
require "fileutils"
FileUtils.ln_sf(assets_path, "public/assets")
end
end
symlink_to_shared_assets
It's working rather nicely.