Comment construire menu emboîtés « arbres » dans HAML
Question
Je suis en train de construire un menu simple html imbriquée à l'aide HAML et ne suis pas sûr de savoir comment s'y prendre pour l'insertion des éléments avec le correct indentation , ou la meilleure façon générale de construire des arbres imbriqués. Je voudrais être en mesure de faire quelque chose comme cela, mais infiniment profond:
- categories.each_key do |category|
%li.cat-item{:id => "category-#{category}"}
%a{:href => "/category/#{category}", :title => "#{category.titleize}"}
= category.titleize
On dirait que je devrais être en mesure d'y arriver assez facilement sans avoir recours à l'écriture des balises à la main en html, mais je ne suis pas le meilleur avec récursivité. Voici le code que je suis actuellement venu avec:
aide de vue
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
Afficher
# 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 d'échantillons définissant Menu
menu:
-
title: "Home"
path: "/home"
-
title: "About Us"
path: "/about"
children:
-
title: "Our Story"
path: "/about/our-story"
Toute idée comment faire de sorte que la sortie est comme ceci:
<ul>
<li class='one two'>
Home
</li>
<li class='one two'>
About Us
</li>
</ul>
... pas comme ça:
<ul>
<li class='one two'>
Home</li>
<li class='one two'>
About Us</li>
</ul>
... et il est donc bien en retrait au niveau mondial.
Merci pour l'aide, Lance
La solution
L'astuce pour bien-retrait, le code généré par Ruby Haml est le aide de haml_tag
. Voici comment je convertir votre méthode de menu_tag
à l'utilisation 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
Autres conseils
Que diriez-vous quelque chose le long des lignes de:
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
Impressionnant, l'indice de @ Shingara me mettre dans la bonne direction :). Cela fonctionne parfaitement:
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
Si quelqu'un peut faire que même plus court, ou le rendre plus facile à personnaliser les attributs sur les noeuds imbriqués, je vais marquer que correcte au lieu de cela.
Vive.
Il est parce que vous envoyez un pur HTML par votre aide. L'indentation avec HAML devenir. Vous pouvez pouvez générer une HAML dans votre aide.