سؤال

أحاول بناء قائمة 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 في المساعد الخاص بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top