Thursday, April 03, 2008

Multisite Rails plugin

It seems like almost every site we create around here needs to be 're-brandable'. Affiliates that market our services want to be able to provide their own face on our sites.

Before I came here the rebranding had been hard coded and pretty awkward. I was able to somewhat simplify it through some rails helper functions that at least allowed us to split up new sites fairly easily.

Well, as usual, I didn't search the plugin repository well enough (OK, at all). Given the latest project that will require rebranding to sell to affiliates, I wanted to come up with a better solution than I had been using before. In a general search for plugins that might be useful to me (he learns!), I found multisite. This plugin allows me to provide different views attached to the same controllers.

After installing the plugin, I generate a new site. Assuming one of the sites I'm creating is called 'mysite.com' I do this from RAILS_ROOT:

script/generate site mysite

The first time generate site is run, it creates the RAILS_ROOT/sites directory, and then inside that, in this case, it creates a 'mysite' directory. The 'mysite' directory contains 2 subdirectories, 'views' and 'public', which should be familiar. The contents of the views directory is structured just as the base view directory is. A directory for each of your controllers, plus a layout directory.

So, any view I have need of should be put here.

Much like the 'layout' command, multisite has the 'site' command, which controls which view directory is used. Add the following to your application.rb controller:

site :which_site

private

def which_site
request.host.split(',',[-2])
end

The which_site function can of course use any method you can think up to determine which site to use. It only has to return the site name that appears in the sites directory.

But what if I have two sites, 'mysite.com' and 'yoursite.com', which mostly have seperate pages, but share a few. Maybe the login page is the same, it just puts the same view in its respective layout template. If that is the case, you only need put that particular view in the base views directory. Using multisite, Rails first looks in the base views dir, and then looks in the multisite views dir if it finds nothing. This can make things a bit confusing, but shouldn't be bad after you're used to it.

You'll notice that the sites directory also contains a 'public' subdir. This is where you can put all your static content, just as in the normal public directory. There is an issue with this particular feature that caused me to not use it. This is a great feature for production, but for me is problematic in development. Access to the views directory is not automatically redirected as with the views directory. You must use Apache to serve those static files. I don't want to run apache on my local machine, so that means I can't properly test my sites locally if I use multisite. I chose to use the base public directory and ignore multisite's version.

There's not much to multisite, but its proving very useful to me.

No comments: