Simple way to specify sidebar in the controller
I'm wrestling with something that should be very simple - specify a sidebar at the controller level. With layouts you can do this:
layout 'admin'
so I'd like to do the same for a sidebar, with something like this:
sidebar 'search'
I know I could specify the sidebar markup with content_for in the views, but I'd rather specify the sidebar at the controller level and not repeat code in (and clutter up) my views. I'd also like to be able to share sidebars between controllers.
At the moment I've got this in an initializer (a plugin seems like overkill for something so simple):
module Sidebar
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def sidebar(partial)
# neither of these two work...
@sidebar = partial
instance_variable_set('@sidebar', partial)
end
end
end
ActionController::Base.send(:include, Sidebar)
and then in my layout I'm trying
<%= render "shared/#{@sidebar}" %>
but to no avail...
Does anyone know what I'm doing wrong, or if indeed I'm go开发者_如何学Going about this the right way at all? Any help is greatly appreciated!
This is a scope issue. The view requires an instance variable but your sidebar method works in the class scope.
module Sidebar
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def sidebar(partial)
before_filter do |controller|
controller.instance_eval { @sidebar = partial }
end
end
end
end
ActionController::Base.send(:include, Sidebar)
If all your controllers include a sidebar, then you can consider to define an instance variable in your application controller.
class ApplicationController < ActionController::Base
attr_accessor :sidebar
end
module Sidebar
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def sidebar(partial)
before_filter do |controller|
controller.sidebar = partial
end
end
end
end
ActionController::Base.send(:include, Sidebar)
Also, if you don't have other methods, you can simplify your mixin even further.
class ApplicationController < ActionController::Base
attr_accessor :sidebar
end
module Sidebar
def sidebar(partial)
before_filter do |controller|
controller.sidebar = partial
end
end
end
ActionController::Base.extend(Sidebar)
Personally I don't like too much this approach. I prefer to define the content of a sidebar in the view file and fallback to a standard value in case no custom value is set.
精彩评论