Come costruire di menu nidificate “alberi” in HAML
Domanda
Sto cercando di costruire un semplice menù nidificato html utilizzando HAML e non sono sicuro di come fare per inserire gli elementi con il corretta indentazione , o il modo migliore per costruire generale alberi annidati. Vorrei essere in grado di fare qualcosa di simile, ma infinitamente profondo:
- categories.each_key do |category|
%li.cat-item{:id => "category-#{category}"}
%a{:href => "/category/#{category}", :title => "#{category.titleize}"}
= category.titleize
Ci si sente come dovrei essere in grado di realizzare questo abbastanza facilmente senza ricorrere alla scrittura dei tag a mano in html, ma io non sono il meglio con la ricorsione. Ecco il codice che ho attualmente venuta in mente:
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
Visualizza
# 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"]
Esempio YAML definire Menu
menu:
-
title: "Home"
path: "/home"
-
title: "About Us"
path: "/about"
children:
-
title: "Our Story"
path: "/about/our-story"
Tutte le idee come fare che così l'output è in questo modo:
<ul>
<li class='one two'>
Home
</li>
<li class='one two'>
About Us
</li>
</ul>
... non in questo modo:
<ul>
<li class='one two'>
Home</li>
<li class='one two'>
About Us</li>
</ul>
... e quindi è corretto rientrato a livello globale.
Grazie per l'aiuto, Lance
Soluzione
Il trucco per ben-frastagliata, codice Haml Ruby-generata è la haml_tag
aiutante . Ecco come mi piacerebbe convertire il vostro metodo di menu_tag
ad usare 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
Altri suggerimenti
Che ne dite qualcosa sulla falsariga di:
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
Impressionante, suggerimento di @ Shingara mi ha messo nella giusta direzione :). Questo funziona perfettamente:
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
Se qualcuno può fare che ancora più breve, o renderlo più facile da personalizzare gli attributi sui nodi nidificati, io lo segnaliamo che come corrette al posto di questo.
Saluti.
E 'perché si invia un HTML pur con il vostro aiuto. Il rientro diventano con HAML. È possibile possibile generare qualche HAML nel vostro aiutante.