Rails Return multiple content_tags from Helper module

11,916

Solution 1

Use #concat:

http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-concat

this thread can be helpful:

rails, How to build table in helper using content_tag?

Solution 2

Since you want to return a series of tags without having to nest them in another tag, and you're dealing with content that comes from an array, this will do the trick:

paragraphs = %w(a b c d e) # some dummy paragraphs
tags = html_escape('') # initialize an html safe string we can append to
paragraphs.each { |paragraph| tags << content_tag(:p, paragraph) }
tags # is now an html safe string containing your paragraphs in p tags

content_tag returns an instance of ActiveSupport::SafeBuffer (which inherits from String). Calling html_escape on an empty string will make that string into an instance of ActiveSupport::SafeBuffer, so when you append the output of content_tag calls to it, you will get all the tags in an html safe string.

(I found this question today when trying to solve this same problem. My solution is years too late for the original question, but will hopefully help someone else!)

Share:
11,916
Ryan King
Author by

Ryan King

Updated on June 11, 2022

Comments

  • Ryan King
    Ryan King almost 2 years

    I've written the following helper:

    def section_to_html (block)
          case block[0].downcase
          when "paragraph"
            block.shift
            block.each do |value|
              return content_tag(:p, value)
            end
          end
      end
    

    It is currently parsed these arrays.

    ["paragraph", "This is the first paragraph."]
    ["paragraph", "This is the second.", "And here's an extra paragraph."]
    

    And it returns:

    <p>This is the first paragraph.</p>
    <p>This is the second.</p>
    

    Is there a way to accumulate the content_tag? so it returns:

    <p>This is the first paragraph.</p>
    <p>This is the second.</p>
    <p>And here's an extra paragraph.</p>
    

    My only solution right now is to use a partial instead. But that's going to get very messy once I starting adding more to case condition.