helper
module ApplicationHelper
def sidebar( args={}, html_options={}, &block )
block_to_partial( ‘shared/sidebar’, args, html_options, block )
end
def block_to_partial( template, args, html_options, block )
template_name = template.split(’/’).last
args = { :title => args, :subtitle => nil } if args.is_a?(String)
&& !args.empty?
html_options[:class] = if html_options[:class].nil?
template_name
else
( html_options[:class].split(’ ‘) << template_name).join(’ ')
end
vars = args.merge! :options => html_options,
:@content_for_layout => capture(&block)
concat render(:partial => template,
:locals => vars), block.binding
end
end
shared/_sidebar.rhtml
<% content_tag ‘div’, options do -%>
<%= content_tag ‘h3’, title %>
<%= content_tag(‘h4’, subtitle) unless subtitle.blank? %>
<%= yield %>
<% end %>
view
<% sidebar ‘Companies’, :id => ‘companies_sidebar’ do %>
<% end %>
explanation
I use the nested_layouts plugin and I find it invaluable… This
helper pattern makes a perfect addition for when I need to pass things
to other layers of my layout. You can use this in your case where you
use content_for.
I found block_to_partial somewhere on the interweb (forgot the source;
if you want credit, speak up!). I customized it so that I can pass a
String as the first parameter, which automatically becomes the title
variable in the partial. Otherwise, I can pass a Hash for the vars
needed in the partial that I don’t want to consider “content”:
sidebar :title=>‘Companies’, :subtitle=>‘Mortgage Brokers’ {…}
rather than yielding these as the content, it lets me render them as
part of the partial, however I might want them commonly formatted in
my partial temlate (DRYness!).
Based on this pattern, I’ve defined other helpers that accomplish
similar tasks. I used title as the only convention for all partials so
I could pass a string for it. This might not be necessary for your
case, and if you need to define other things instead, you can just
pass a hash when you call it.
It works well for all my needs. Improvements? Suggestions?
–Andrew V.