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

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top