2010-03-11 28 views
4

我正在嘗試使用HAML構建一個簡單的嵌套HTML菜單,我不知道如何去插入correct indentation的元素,或者構建嵌套樹的最佳方法。我希望能夠做這樣的事情,但無限深:如何在HAML中構建嵌套菜單「樹」

- categories.each_key do |category| 
    %li.cat-item{:id => "category-#{category}"} 
     %a{:href => "/category/#{category}", :title => "#{category.titleize}"} 
      = category.titleize 

這種感覺就像我應該能夠不訴諸於HTML手寫標籤很容易地做到這一點,但我遞歸不是最好的。這是目前我想出代碼:

視圖助手

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"] 

樣品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> 

...等等這是正確的縮進全球。

感謝您的幫助, 蘭斯

回答

5

很好的縮進,Ruby生成的Haml代碼的技巧是haml_tag helper。以下是我想你menu_tag方法轉換爲使用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 
-2

這是因爲你通過你的助手發送PUR HTML。縮進成爲HAML。你可以在你的助手中生成一些HAML。

+0

它不能夠實際產生的helper Haml的代碼,並且它可以動態渲染成HTML(除非你手動調用Haml的編譯器)。 – 2010-03-11 08:25:41

0

真棒,@ shingara的暗示把我在正確的方向:)。這完美的作品:

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 

如果有人可以使更短,或使其更容易定製的嵌套節點的屬性,我將標誌着作爲正確的,而不是這個。

乾杯。

3

如何沿着線的東西:

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 
+0

這是haml_concat的美妙使用,我能夠在大約五分鐘內使這種技術在我的應用程序中工作。非常感謝! – slothbear 2014-11-30 23:20:23