我正在尝试编写一个Rails帮助器方法,将嵌套的哈希转换为嵌套的HTML列表。
例如:
{
:parent => "foo",
:children => [
{
:parent => "bar",
:children => [
{
:parent => "baz",
:children => []
}
]
}
]
}
应该成为:
<ul>
<li>foo</li>
<ul>
<li>bar</li>
<ul>
<li>baz</li>
</ul>
</ul>
</ul>
散列可以包含任意数量的级别,以及每个级别的任意数量的父级。
最好的方法是什么?
答案 0 :(得分:5)
您可以使用递归方法渲染以散列到嵌套的列表集。将其放在您的相关助手中:
def hash_list_tag(hash)
html = content_tag(:ul) {
ul_contents = ""
ul_contents << content_tag(:li, hash[:parent])
hash[:children].each do |child|
ul_contents << hash_list_tag(child)
end
ul_contents.html_safe
}.html_safe
end
答案 1 :(得分:1)
Zach Kemp的回答非常有效地解决了这个问题。如果你正在寻找一些更通用的东西(一个你不知道密钥名称的嵌套哈希),就像我一样,以下模块可能会有所帮助(同样在https://github.com/sjohnson/auto_hash_display有更多细节):
module HashFormatHelper
# These methods add classes to the HTML structure that are defined in Bootstrap (and can be defined for other CSS frameworks)
def format_hash(hash, html = '')
hash.each do |key, value|
next if value.blank?
if value.is_a?(String) || value.is_a?(Numeric)
html += content_tag(:ul, class: 'list-group') {
ul_contents = ''
ul_contents << content_tag(:li, content_tag(:h3, key.to_s.underscore.humanize.titleize), class: 'list-group-item')
ul_contents << content_tag(:li, value, class: 'list-group-item')
ul_contents.html_safe
}
elsif value.is_a?(Hash)
html += content_tag(:ul, class: 'list-group') {
ul_contents = ''
ul_contents << content_tag(:li, content_tag(:h3, key.to_s.underscore.humanize.titleize), class: 'list-group-item')
inner = content_tag(:li, format_hash(value), class: 'list-group-item')
ul_contents << inner
ul_contents.html_safe
}
elsif value.is_a?(Array)
html += format_array(value)
else
Rails.logger.info "Unexpected value in format_hash: #{value.inspect}"
Rails.logger.info "value type: #{value.class.name}"
end
end
html.html_safe
end
def format_array(array, html = '')
array.each do |value|
if value.is_a?(String)
html += content_tag(:div, value).html_safe
elsif value.is_a?(Hash)
html += format_hash(value)
elsif value.is_a?(Array)
html += format_array(value)
else
Rails.logger.info "Unexpected value in format_array: #{value.inspect}"
Rails.logger.info "value type: #{value.class.name}"
end
end
html
end
end
此代码也可用于通过将哈希值设置为等于Hash.from_xml(your_xml_data)然后将其传递给format_hash(哈希)来显示XML。
请注意,from_xml方法可能会剥离XML标记属性,因此最适合没有属性的XML。