Search code examples
ruby-on-railsrubyrefinerycmsapotomo

Integrating apotomo with RefineryCMS pages


I'd like to extend RefineryCMS's PagesController to use some apotomo widgets in our project.

I could potentially do an "override" of the PagesController, which copies it into my project, but I'm using another engine that extends the PagesController (modifying the show and home methods using a module/monkey patching approach) I'd rather avoid that.

My initial approach was something like this:

in config/application.rb:

config.before_initialize do
  require 'pages_controller_extensions'
end

config.to_prepare do
  PagesController.send :include, Refspike::Extensions
end

In pages_controller_extensions:

module Refspike
  module Extensions
    class << PagesController
      include Apotomo::Rails::ControllerMethods
      has_widgets do |root|
        root << widget(:map)
      end
    end
  end
end

Unfortunately this blows up on the line "helper ActionViewMethods" in apotomo's controller_methods. Adding include Apotomo::Rails::ActionViewMethods didn't help.

I presume I'm just getting a basic detail about rails dependency management or maybe ruby open classes wrong. Is there an alternative approach, or something simple I'm overlooking?


Solution

  • Here's the solution. Remove the before_initialize stuff; there's simply no need for this to be in a module. In application.rb, do:

    config.to_prepare do
      ::PagesController.send :include, Apotomo::Rails::ControllerMethods
      ::PagesController.has_widgets do |root|
        root << widget(:map)
      end
    end
    

    Then, override refinery's shared/_content_page.html.erb to include:

    <%=render_widget :map %>
    

    Done and done.

    What was wrong before? Well, calling ::PagesController.send :include, Refspike::Extensions means that I'm actually "almost" in the scope of the class I'm trying to modify, but not quite. So, reopening the class is unnecessary, for one thing. But an ActiveSupport method, class_inheritable_array being called by apotomo, apparently isn't discoverable in my module scope, either, so I can't get away with doing something like:

    #doesn't work
    module Refspike
      module Extensions
        include Apotomo::Rails::ControllerMethods
        has_widgets do |root|
          root << widget(:map)
        end
      end
    end
    

    Fortunately, the 4 lines of code in the application.rb are a simpler solution, and that does the trick for me.