我正在尝试使用HAML构建一个简单的嵌套html菜单,并且不确定如何使用correct indentation插入元素,或者是构建嵌套树的一般最佳方法。我希望能够做到这样的事情,但无限深刻:
- categories.each_key do |category|
%li.cat-item{:id => "category-#{category}"}
%a{:href => "/category/#{category}", :title => "#{category.titleize}"}
= category.titleize
感觉就像我应该能够很容易地完成这一点而不需要在html中手工编写标签,但我不是最好的递归。以下是我目前提出的代码:
查看助手
def menu_tag_builder(array, &block)
return "" if array.nil?
result = "<ul>\n"
array.each do |node|
result += "<li"
attributes = {}
if block_given?
text = yield(attributes, node)
else
text = node["title"]
end
attributes.each { |k,v| result += " #{k.to_s}='#{v.to_s}'"}
result += ">\n"
result += text
result += menu_tag_builder(node["children"], &block)
result += "</li>\n"
end
result += "</ul>"
result
end
def menu_tag(array, &block)
haml_concat(menu_tag_builder(array, &block))
end
查看
# index.haml, where config(:menu) converts the yaml below
# to an array of objects, where object[:children] is a nested array
- menu_tag(config(:menu)) do |attributes, node|
- attributes[:class] = "one two"
- node["title"]
示例YAML定义菜单
menu:
-
title: "Home"
path: "/home"
-
title: "About Us"
path: "/about"
children:
-
title: "Our Story"
path: "/about/our-story"
任何想法如何做到这样输出是这样的:
<ul>
<li class='one two'>
Home
</li>
<li class='one two'>
About Us
</li>
</ul>
......不喜欢这样:
<ul>
<li class='one two'>
Home</li>
<li class='one two'>
About Us</li>
</ul>
...所以它在全球范围内正确缩进。
感谢您的帮助, 兰斯
答案 0 :(得分:5)
巧妙缩进的技巧,Ruby生成的Haml代码是haml_tag
helper。以下是我将menu_tag
方法转换为使用haml_tag
的方法:
def menu_tag(array, &block)
return unless array
haml_tag :ul do
array.each do |node|
attributes = {}
if block_given?
text = yield(attributes, node)
else
text = node["title"]
end
haml_tag :li, text, attributes
menu_tag_builder(node["children"], &block)
end
end
end
答案 1 :(得分:3)
如何处理以下内容:
def nested_list(list)
return unless list
haml_tag :ul do
list.each do |item|
haml_tag :li do
haml_concat link_to item["title"], item["path"]
if item["children"]
nested_list item["children"]
end
end
end
end
end
答案 2 :(得分:0)
太棒了,@ shingara的提示让我朝着正确的方向前进:)。这非常有效:
def menu_tag(array, &block)
return "" if array.nil?
haml_tag :ui do
array.each do |node|
attributes = {}
if block_given?
text = yield(attributes, node)
else
text = node[:title]
end
haml_tag :li, attributes do
haml_concat text
menu_tag_builder(node[:children], &block)
end
end
end
end
如果某人可以做得更短,或者更容易在嵌套节点上自定义属性,我会将其标记为正确而不是此。
干杯。
答案 3 :(得分:-2)
这是因为你的帮助者发送了一个pur HTML。缩进成为HAML。您可以在助手中生成一些HAML。