对于我的应用程序,将有趣的html生成结构化为一组看起来像form_for的调用将会很有帮助。这是一个例子,来自_reports.html.erb:
<%= reports_list do |rep| %>
<%= rep.group_header("Reports by Question") do %>
<%= rep.title("Response Distribution") %>
<%= rep.description do %>
lorem lorem lorem
lorem lorem lorem
<%= end %>
<%= rep.title("Response Distribution") %>
<%= rep.description do %>
lorem lorem lorem
lorem lorem lorem
<%= end %>
<%= end %>
<%= end %>
这些调用中的每一个都会生成一些带有css和标签的html等等,这会完全模糊这个报表列表的结构。
我尝试过阅读form_for,但是我无法将其解读为我需要的模式。任何人都有这方面的想法,和/或一个提炼问题的链接?谢谢!
答案 0 :(得分:1)
您可以编写一个小型自定义DSL(您可以改进并使代码更好):
可以大大改进的小型DSL:
class ReportHtmlMaker
def initialize(output)
@output = output
end
def content(text)
@output << text.to_s
nil
end
def translate_semantic_tag(tagname,attributes={})
newline = "" # "\r\n" uncomment to add newlines
case tagname.to_sym
when :group_header
tagname = "h1"
attributes[:id] = "report_group_header"
when :title
tagname = "h2"
attributes[:class] = "report_title"
when :description
tagname = "p"
end
@output << "<#{tagname}"
attributes.each { |attr,value| @output << " #{attr}='#{value}'" }
if block_given?
@output << ">" << newline
content = yield
if content
@output << content.to_s << newline
end
@output << "</#{tagname}>" << newline
else
@output << "/>" << newline
end
nil
end
alias method_missing translate_semantic_tag
def self.generate(output, &block)
ReportHtmlMaker.new(output).instance_eval(&block)
end
end
用法:
output = String.new
ReportHtmlMaker.generate(output) do #or, use STDOUT to output to console
group_header do
title do
"Response Distribution"
end
description do
"lorem ipsum dolor mit"
end
end
end
输出:
puts output # =>
<div id='report_group_header'>
<h2 class='report_title'>Response Distribution</h2>
<p class='report_description'>lorem ipsum dolor mit</p>
</h1>
那是你在找什么?