Posts tagged rails 2.3

Rails 2.3 final and theme_support updates

Somewhere between Ruby on Rails versions 2.3.0 (RC1) and 2.3.2 (final) a change was made to the arguments required for one of the methods the theme_support plugin requires. I must confess I hadn’t spotted it, but github user knapo kindly sent me a message with a patch. That patch is now applied in the main repository, as are a few tweaks to the ActionMailer integration to better handle multipart emails. You can get the new version from github.

Perhaps more significant than those small patches is that I’ve now pushed up a new rails app for use in testing theme_support. The tests are a series of cucumber stories, and the app is very barebones designed entirely to test the various features. I could do with tightening up the way the test app and the main plugin repository are connected, but it’s a start and has been very helpful with the aforementioned patches. Any improvements to the test suite would be much appreciated. You can, of course, find it on github.

Rails 2.3 and theme_support part 3: Layouts

In my ongoing efforts to bring my fork of theme_support in line with Rails 2.3 I’ve covered the core views and email, but when I left off earlier today layouts still weren’t working.

The key problem with overriding layouts is that the process of identifying them relies on some class methods on ActionController::Base (provided in the ActionController::Layout module). Roughly put we have:

  1. ActionController::Base#render calls ActionController::Base#pick_layout
  2. ActionController::Base#pick_layout checks to see if there’s a specific layout requested and calls ActionController::Base#active_layout
  3. ActionController::Base#active_layout checks whether there’s a candidate layout for this controller or action and makes sure the layout exists by calling ActionController::Base.find_layout
  4. ActionController::Base.find_layout (class method) is called which checks the view_paths to find the appropriate layout in there

The issue is that as a class method ActionController::Base.active_layout has no knowledge of the specific controller instance, or the request object it contains, and so it can’t access our logic to determine the current theme.

One option would be to patch a number of these methods to hand a controller instance around which could be queried for the theme, but that seems rather clunky.

Another option is to wrap the active_layout method so that it (as an instance method) checks whether there is a current theme and if so, adds that theme’s path to the class level view_paths, removing it again after that check:

  class ActionController::Base
    alias_method :theme_support_active_layout, :active_layout
 
    def active_layout(passed_layout = nil)
      if current_theme
        theme_path = File.join(RAILS_ROOT, "themes", controller.current_theme, "views")
        if File.exists?(theme_path) and ! self.class.view_paths.include?(theme_path)
          self.class.view_paths.unshift(theme_path)
          result = theme_support_active_layout(passed_layout)
          self.class.view_paths.shift
          return result
        end
      end
 
      theme_support_active_layout(passed_layout)
    end
  end

And it works!

So that’s views, emails and now layouts all working with theme_support on Rails 2.3. As before, you can get the results in the branch on github:

http://github.com/jystewart/theme_support/tree/rails-2-3-support

Over the next couple of weeks I’m hoping to test my patches on other releases in the 2.x series, probably using a test app with specs or stories that will put it through its paces. Once that’s done I may turn my attention to the other corners of the plugin (that I don’t personally use) like the asset helper methods, but if anyone wants to contribute patches in the meantime I’d love to get them.