hypern
hypern

Reputation: 887

content_tags inside of a content_tag

When I nest more than one other content_tag inside of a content_tag, only the most recently nested tag is included in the HTML output.

I am creating a helper function that creates a bootstrap navbar:

def navigation_menu
    content_tag(:nav, class: "navbar navbar-default") do
        content_tag(:div, class: "container") do
            content_tag(:div, class: "navbar-header") do
                button_tag(type: "button", class: "navbar-toggle collapsed") do
                    content_tag(:span, "Toggle navigation", class: "sr-only")
                    content_tag(:span, class: "icon-bar")
                    content_tag(:span, class: "icon-bar")
                    content_tag(:span, class: "icon-bar")
                end
                content_tag(:a, "Brand", {class: "navbar-brand", href: "#"})
            end
            content_tag(:div, class: "collapse navbar-collapse") do
                content_tag(:ul, class: "nav navbar-nav") do
                    content_tag(:li) do
                        link_to "Companies", companies_path
                    end
                    content_tag(:li) do
                        link_to "Servers", servers_path
                    end
                end
            end
        end
    end
end

This results in a navbar with only the 'server' list item included:

<nav class="navbar navbar-default">
  <div class="container">
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li><a href="/servers">Servers</a></li>
      </ul>
    </div>
  </div>
</nav>

What changes do I need to make to my code in order to produce the expected boostrap menu?

Upvotes: 2

Views: 2425

Answers (1)

sockmonk
sockmonk

Reputation: 4255

It looks like you're actually pretty close. The thing to remember is that content_tag returns an HTML string. When several are nested directly, it works out fine. But when you have two or more content_tag expressions at the same nested level, only the last one gets returned to the surrounding block; earlier ones don't get stored anywhere, and aren't the result of the block.

I see only two places where you have two content_tag blocks at the same nesting level. The simplest way to fix it might be to do something like:

tag1 = content_tag( ... )
tag2 = content_tag( ... )
(tag1 + tag2).html_safe

That html_safe may or not be needed; you can try it both ways to see. If so, it's only because of the string concatenation. Other than that, what you have looks fine.

Upvotes: 2

Related Questions