== So... Themer. What is that thing for? For something blatantly called "theming". To do it in Rails you have two options. The first one is to try this http://weblog.techno-weenie.net/2005/11/4/more_on_per_request_template_roots_in_actionpack However, this is very hackish - first of all, you will need exactly the same structure as in the standard "views" (not exactly flexible). Second - you are still tying yourself into a class variable (not inheritable). The second one (if you are on Edge Rails) happens to be "set yourself on fire and run in circles". The template lookup that is currently implemented in Edge Rails kills the custom template paths on just about every occasion. Behold: http://dev.rubyonrails.org/ticket/8582 http://dev.rubyonrails.org/ticket/7889 Exactly one of the cases when you don't want to be following Edge thusly. There are theming plugins, all of them hack ActionView in one way or another and all of them get obsolete very fast. == The solution I decided to leave ActionView and friends alone and implement a template lookup system on top of standard Rails rendering pipeline. Consider you have a site which has a "theme" field. Then you have a "themes" directory under your /app dir. class ThemedController < ApplicationController before_filter :select_theme private def select_theme # Lets assume the site called 'snow' is being requested @site = Site.find_by_domain(request.host) @themer = Themer::Base.new :special_subdir => @site.domain end end Like this you create a template lookup object that will search for templates in this directory. After that, when you need to render, call render :action => 'view_post', :themer => @themer The object will then look for a suitable layout under the following directories: RAILS_ROOT/app/views-per-site/snow/layouts/layout.rhtml RAILS_ROOT/app/views-per-site/_base/layouts/layout.rhtml Same will happen with partials and actions - just pass your usual options to +render+ == The pros This has a number of advantages. First, it takes special files over shared ones (in contrast to Rails, which does the reverse) - so you can "overlay" specific templates per theme. Secondly, the template lookup class is customizable. You can implement a template lookup that is dependent on the current time of day, for example. Or you can flush your templates stored in the database to disk and go from there. It's more flexible than render :inline because you will get cached templates. There is also much less chance of the thing breaking because we just use public APIs here. All the file lookups performed will be cached (you won't be globbing all anew all the time). If you got a directory chock full of templates which have to be shuffled in the middle of the lifetime of the application, do Themer::Base.flush_cache! to flush the cached lookups (for all Themers). And besides we call out to standard template rendering engine of Rails, so all custom templates and options just continue working == Compatibility Themer works both with Edge and gem rails. It calls out to template_root of the controller but as a consumer (without overriding anything), so it should be relatively safe. == Tip: time-based theming class CalendarController < ApplicationController def index day_for_night = Themer::Base.new (Time.now.hours > 12 ? "day" : "night") render :themer => day_for_night end end In conclusion ============= Let's hope that core will get its act together with respect to this. Just looking at action_view/base.rb gives you shudders. Questions? me[at]julik[dot]nl