Same site, multiple branding. Putting out the feelers...

Just putting out some general feelers and wondering if anyone has
tackled this issue before in Rails.

I've done it in something other than Rails, but the methodology is simple enough, that it doesn't really matter if it is Rails or not.

Something along the lines of allowing different customers to run their
own mini sites from within the main one to get all the applications and
tools provided by that site. But with the crucial ability to choose
their own layout and colour schemes and drag'n'drop in the services they
want to run as well. Something like:

http://myportal… .or.
http://…/myportal

IMO the preferred way is to use subdomains, which I described in this article:
http://www.railsdev.ws/blog/10/using-subdomains-in-rails-apps/

As for themes, this isn't as hard as it sounds. First, you need to use really clean HTML so that CSS can take care of the vast majority of the work. You want each theme to be its own CSS file(s) which is easy to programmatically define in the page <head>.

Depending on how radically different you want each theme, you can use different layouts to assemble partials in a different order etc. Again, the name of the layout can be declared programatically.

Between combining unique layouts and CSS files you have the majority of the work done. All that's left is a file structure that makes it easy to add & remove themes. Another article on that same site looks at organizing modular site structures which would apply well to themes.

Additionally, in my apps I use a simple object called sitePaths for all paths within the app. Something like this:

class SitePaths

attr_reader :layouts, :controls, :edpNavImgs, :panels, :mastheadViews, :mastheadImgs,
      :images, :audio, :video, :flash, :downloads

def initialize

   @layouts = '/layouts/'
   @panels = '_panels/'
   @controls = '/controls/'
   @mastheadViews = '/layouts/masthead/'
   @mastheadImgs = '/masthead/images/'

   @images = '/media/images/'
   @audio = '/media/audio/'
   @video = '/media/video/'
   @flash = '/media/flash/'
   @downloads = '/media/downloads/'

end

I declare an object @sitePaths in application.rb so everywhere there's a need for a path, I can do something like

    @sitePaths.controls + 'btnFormSave.gif'

If the site needs to support themes, I simply modify the above SitePaths code to allow for a theme name:

def initialize(themeName)
   @layouts = "/#{themeName}/layouts/"
   @panels = '_panels/' # not affacted by themes
   @controls = "/#{themeName}/controls/"
   @mastheadViews = "/#{themeName}/layouts/masthead/"
   @mastheadImgs = "/#{themeName}/masthead/images/"
   ...
end

The application code stays exactly the same:

    @sitePaths.controls + 'btnFormSave.gif'

But now the location of that file is programmatically altered by pulling a theme name from an accont profile stored under the name of the site subdomain.

Given the new asset stuff in Rails 2.0...

I had a very quick look at that, and it seems to be quite similar to the system I built into my own framework years ago to support this very kind of site you're looking at. I was thinking I'd have to add my own layer to deal with that, so it'd be cool to see Rails have something built in.

Really, that's all there is to it in terms of taking care of layout and appearance. As far as assembling collections of different functionalities per sub-site, that's just a little more work in providing a UI for the user to select what they want to build a data structure defining a layout and the contents of each layout panel, and making the innards of your layouts use variables to determine which partial will be loaded into each panel.

-- gw (www.railsdev.ws)