Я использую нечто подобное в моих шаблонах. Вот модификация. Это должно работать в Rails 3.
application_helper.rb:
module ApplicationHelper
class PageBuilder
def initialize(title, template)
@title, @template = title, template
@header, @body, @sidebar = nil, nil, nil
@options = { :page => {} , :header => {}, :sidebar => {}, :body => {}, :title => {} }
@logger = Rails.logger
end
def parse(&block)
if block_given?
if @template.respond_to?(:is_haml?) && @template.is_haml?
contents = @template.capture_haml(&block)
else
#erb
contents = @template.capture(&block)
end
else
contents = ""
end
contents
end
def page (options,&block)
options[:class] ||= "page"
@options[:page] = options
parse(&block)
content = ""
content += @template.content_tag(:title, @options[:title]) { @title } unless @title.nil?
content += @template.content_tag(:header,@options[:header]) do
@template.content_tag( :h1) { @header }
end unless @header.nil?
content += @template.content_tag(:asside, @options[:sidebar]) { @sidebar } unless @sidebar.nil?
content += @template.content_tag(:section, @options[:section]) { @body } unless @body.nil?
return @template.content_tag(:div, @options[:page]) { content.html_safe }
end
def header(options={},&block)
@options[:header] = options
@header = parse(&block)
nil
end
def sidebar(options={},&block)
@options[:sidebar] = options
@sidebar = parse(&block)
nil
end
def body(options={},&block)
@options[:body] = options
@body = parse(&block)
nil
end
end
def page_for(title, options = {}, &block )
raise ArgumentError, "Missing block" unless block_given?
builder = PageBuilder.new(title, view_context )
return builder.page(options) do
block.call(builder)
end
end
end
Теперь, в вашем примере кода, когда page.has_sidebar? == false
, вы получите
<div class="page"><title>Super Cool Page</title><header><h1>
Ruby is Cool
</h1></header><section>
Witty discourse on Ruby.
</section></div>
и когда page.has_sidebar? == true
, вы получите
<div class="page"><title>Super Cool Page</title><header><h1>
Ruby is Cool
</h1></header><asside>
<ul><li>Option 1</li></ul>
</asside><section>
Witty discourse on Ruby.
</section></div>
Вы можете изменить порядок вещей в методе page
, чтобы получить любой желаемый макет в качестве вывода.