这就是我想在index.html.erb中编写标记的方式
<%= page_for "Super Cool Page" do |p| %>
<%= p.header do %>
Ruby is Cool
<% end %>
<%= p.body do %>
Witty discourse on Ruby.
<% end %>
<% if page.has_sidebar? %>
<%= p.sidebar do %>
<ul><li>Option 1</li></ul>
<% end %>
<% end %>
<% end %>
哪个会输出
<div class="page">
<header><h1>Super Cool Page</h1></header>
<section>
Witty discourse on Ruby.
</section>
</div>
当page.has_sidebar?是真的
<div class="page">
<header><h1>Super Cool Page</h1></header>
<asside><ul><li>Option 1</li></ul></asside>
<section>
Witty discourse on Ruby.
</section>
</div>
我已经看过rails中的FormHelper类以获得指导,但似乎我必须复制我正在努力避免的大量工作.我只是想弄清楚在框架中挂起类/模块/方法的位置以及对象| p |的类型应该.
我的第一个倾向是创建一个实现header,body和sidebar方法的PageBuilder类.但是我被困在渲染管道上以使所有输出正确.
是否有一个已经提供此类语义生成的gem?如果不是,我会喜欢任何关于如何设置它的见解.
最佳答案 我在模板中使用类似的东西.这是一个修改.这应该适用于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? ==是的,你会得到的
<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>
您可以在页面方法中重新排列内容以获得任何所需的布局作为输出.