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?
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.