Loop & output content_tags within content_tag in helper

后端 未结 5 1521
我在风中等你
我在风中等你 2020-12-23 11:45

I\'m trying a helper method that will output a list of items, to be called like so:

foo_list( [\'item_one\', link_to( \'item_two\', \'#\' ) ... ] )


        
相关标签:
5条回答
  • 2020-12-23 12:17

    You could use content_tag_for, which works with collections:

    def foo_list(items)
      content_tag(:ul) { content_tag_for :li, items }
    end
    

    Update: In Rails 5 content_tag_for (and div_for) were moved into a separate gem. You have to install the record_tag_helper gem in order to use them.

    0 讨论(0)
  • 2020-12-23 12:17

    Along with answers above, this worked for me well:

    (1..14).to_a.each do |age|
      concat content_tag :li, "#{link_to age, '#'}".html_safe
    end
    
    0 讨论(0)
  • 2020-12-23 12:29

    I couldn't get that work any better.

    If you were using HAML already, you could write your helper like this:

    def foo_list(items)
      haml_tag :ul do
        items.each do |item|
          haml_tag :li, item
        end
      end
    end
    

    Usage from view:

    - foo_list(["item_one", link_to("item_two", "#"), ... ])
    

    Output would be correctly intended.

    0 讨论(0)
  • 2020-12-23 12:32

    The big issue is that content_tag isn't doing anything smart when it receives arrays, you need to send it already processed content. I've found that a good way to do this is to fold/reduce your array to concat it all together.

    For example, your first and third example can use the following instead of your items.map/collect line:

    items.reduce(''.html_safe) { |x, item| x << content_tag(:li, item) }
    

    For reference, here is the definition of concat that you're running into when you execute this code (from actionpack/lib/action_view/helpers/tag_helper.rb).

    def concat(value)
      if dirty? || value.html_safe?
        super(value)
      else
        super(ERB::Util.h(value))
      end
    end
    alias << concat
    
    0 讨论(0)
  • 2020-12-23 12:36

    Try this:

    def foo_list items
      content_tag :ul do
          items.collect {|item| concat(content_tag(:li, item))}
      end
    end
    
    0 讨论(0)
提交回复
热议问题