我正在尝试一个帮助方法,它将输出一个项目列表,如下所示:
foo_list( ['item_one', link_to( 'item_two', '#' ) ... ] )
我在阅读Using helpers in rails 3 to output html之后写了这样的帮手:
def foo_list items
content_tag :ul do
items.collect {|item| content_tag(:li, item)}
end
end
然而,在这种情况下我只是得到一个空的UL,如果我这样做是为了测试:
def foo_list items
content_tag :ul do
content_tag(:li, 'foo')
end
end
我获得了UL&李如预期。
我已经尝试过将其交换一下:
def foo_list items
contents = items.map {|item| content_tag(:li, item)}
content_tag( :ul, contents )
end
在这种情况下,我获得了整个列表,但LI标签是html转义的(即使字符串是HTML安全的)。做content_tag(:ul, contents.join("\n").html_safe )
有效,但我感觉不对,我觉得content_tag
应该以某种方式在某个集合模式下工作。
答案 0 :(得分:49)
试试这个:
def foo_list items
content_tag :ul do
items.collect {|item| concat(content_tag(:li, item))}
end
end
答案 1 :(得分:8)
我无法更好地完成这项工作。
如果您已经使用HAML,可以像这样编写助手:
def foo_list(items)
haml_tag :ul do
items.each do |item|
haml_tag :li, item
end
end
end
从视图中使用:
- foo_list(["item_one", link_to("item_two", "#"), ... ])
输出是正确的。
答案 2 :(得分:5)
您可以使用content_tag_for
,它适用于集合:
def foo_list(items)
content_tag(:ul) { content_tag_for :li, items }
end
更新:在Rails 5中,content_tag_for
(和div_for
)被移动到一个单独的gem中。您必须安装record_tag_helper
gem才能使用它们。
答案 3 :(得分:3)
除了上面的答案,这对我很有用:
(1..14).to_a.each do |age|
concat content_tag :li, "#{link_to age, '#'}".html_safe
end
答案 4 :(得分:2)
最大的问题是,在收到数组时,content_tag没有做任何聪明的事情,你需要发送已处理过的内容。我发现这样做的一个好方法是折叠/缩小你的数组以便将它们连接在一起。
例如,您的第一个和第三个示例可以使用以下内容代替您的items.map/collect行:
items.reduce(''.html_safe) { |x, item| x << content_tag(:li, item) }
作为参考,这里是执行此代码时遇到的concat的定义(来自actionpack / lib / action_view / helpers / tag_helper.rb)。
def concat(value)
if dirty? || value.html_safe?
super(value)
else
super(ERB::Util.h(value))
end
end
alias << concat