Wie verschachtelte Menü „Bäume“ in HAML bauen
Frage
Ich versuche, ein einfaches verschachtelten HTML-Menü erstellen mit HAML und bin nicht sicher, wie das Einsetzen der Elemente mit dem richtige Vertiefung , oder der allgemeine beste Weg, verschachtelte Bäume zu bauen. Ich möchte in der Lage sein, so etwas zu tun, aber unendlich tief:
- categories.each_key do |category|
%li.cat-item{:id => "category-#{category}"}
%a{:href => "/category/#{category}", :title => "#{category.titleize}"}
= category.titleize
Es fühlt sich an wie ich in der Lage sein sollte, das ist ziemlich leicht zu schreiben, die Tags von Hand in html ohne Rückgriff zu erreichen, aber ich bin nicht die beste mit Rekursion. Hier ist der Code, den ich zur Zeit habe kommen mit:
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
# 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"]
Beispiel YAML definieren Menü
menu:
-
title: "Home"
path: "/home"
-
title: "About Us"
path: "/about"
children:
-
title: "Our Story"
path: "/about/our-story"
Irgendwelche Ideen, wie man das so die Ausgabe wie folgt lautet:
<ul>
<li class='one two'>
Home
</li>
<li class='one two'>
About Us
</li>
</ul>
... nicht wie folgt aus:
<ul>
<li class='one two'>
Home</li>
<li class='one two'>
About Us</li>
</ul>
... und so ist es richtig eingerückt global.
Danke für die Hilfe, Lance
Lösung
Der Trick, um schön gegliederte, Rubin-generierte Haml Code ist die haml_tag
Helfer . Hier ist, wie ich Ihre menu_tag
Methode zur Verwendung von haml_tag
umwandeln würde:
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
Andere Tipps
Wie wäre es etwas entlang der Linien von:
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
Awesome, Tipp des @ Shingara setzte mich in der richtigen Richtung :). Das funktioniert perfekt:
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
Wenn jemand kann, dass noch kürzer machen, oder macht es leicht, die Attribute auf dem verschachtelten Knoten anpassen, ich das als richtig markieren werde statt dem.
Prost.
Es ist, weil Sie einen pur HTML, indem Sie Ihre Helfer senden. Die Vertiefung mit HAML werden. Sie können können einige HAML in Ihrem Helfer erzeugen.