كيفية بناء قائمة متداخلة "الأشجار" في هامل
سؤال
أحاول بناء قائمة HTML متداخلة بسيطة باستخدام 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>
... وحتى بادئة بشكل صحيح على مستوى العالم.
شكرا للمساعدة، انس
المحلول
الخدعة إلى رمز HAML Ruby-Ruby-Ruby haml_tag
المساعد. وبعد إليك كيف أقوم بتحويلك 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
نصائح أخرى
ماذا عن شيء على غرار:
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
رهيبة، تلميح شينغارا في الاتجاه الصحيح :). هذا يعمل تماما:
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
إذا كان بإمكان شخص ما أن يجعل ذلك أقصر، أو جعله أكثر سهولة في تخصيص السمات الموجودة على العقد المتداخلة، فسوف أحصل على ذلك صحيحا بدلا من ذلك.
هتافات.
ذلك لأنك ترسل Pur HTML عن طريق المساعد الخاص بك. البادئة تصبح مع حمل. يمكنك إنشاء بعض Haml في المساعد الخاص بك.