如何构建嵌套菜单“树”在 HAML 中
我正在尝试使用 HAML 构建一个简单的嵌套 html 菜单,但不确定如何使用 正确缩进,或者构建嵌套树的一般最佳方法。我希望能够做这样的事情,但无限深:
- categories.each_key do |category|
%li.cat-item{:id => "category-#{category}"}
%a{:href => "/category/#{category}", :title => "#{category.titleize}"}
= category.titleize
感觉我应该能够很容易地完成这个任务,而无需在 html 中手动编写标签,但我不是最擅长递归的。以下是我目前提出的代码:
View Helper
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
View
# 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>
...因此它在全球范围内正确缩进。
感谢您的帮助, 槊
I am trying to build a simple nested html menu using HAML and am not sure how to go about inserting the elements with the correct indentation, or the general best way to build nested trees. I would like to be able to do something like this, but infinitely deep:
- categories.each_key do |category|
%li.cat-item{:id => "category-#{category}"}
%a{:href => "/category/#{category}", :title => "#{category.titleize}"}
= category.titleize
It feels like I should be able to accomplish this pretty easily without resorting to writing the tags by hand in html, but I'm not the best with recursion. Here is the code I've currently come up with:
View Helper
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
View
# 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"]
Sample YAML defining Menu
menu:
-
title: "Home"
path: "/home"
-
title: "About Us"
path: "/about"
children:
-
title: "Our Story"
path: "/about/our-story"
Any ideas how to do that so the output is like this:
<ul>
<li class='one two'>
Home
</li>
<li class='one two'>
About Us
</li>
</ul>
...not like this:
<ul>
<li class='one two'>
Home</li>
<li class='one two'>
About Us</li>
</ul>
... and so it's properly indented globally.
Thanks for the help,
Lance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Ruby 生成的 Haml 代码的缩进良好的技巧是
haml_tag
助手。以下是我将menu_tag
方法转换为使用haml_tag
的方法:The trick to nicely-indented, Ruby-generated Haml code is the
haml_tag
helper. Here's how I'd convert yourmenu_tag
method to usinghaml_tag
:类似这样的事情怎么样:
How about something along the lines of:
太棒了,@shingara 的提示让我找到了正确的方向:)。这非常有效:
如果有人可以使其变得更短,或者使其更容易自定义嵌套节点上的属性,我会将其标记为正确而不是此。
干杯。
Awesome, @shingara's hint put me in the right direction :). This works perfectly:
If somebody can make that even shorter, or make it more easy to customize the attributes on the nested nodes, I'll mark that as correct instead of this.
Cheers.
这是因为你的助手发送了一个 pur HTML。缩进变为 HAML。您可以在助手中生成一些 HAML。
It's because you send a pur HTML by your helper. The indentation become with HAML. You can can generate some HAML in your helper.