bricker
bricker

Reputation: 8941

DRY, Short, and Conventional helper which returns multiple lines of HTML

I'm looking for the DRYest, most conventional, and shortest way to write this helper.

I have something like this at the top of each index view file:

<%= page_header "Blog", "My thoughts on things" %>

And the corresponding helper:

def page_header(title=nil, subtitle=nil)
  header = ''
  header += content_tag(:h1, title) if title.present?
  header += content_tag(:h3, subtitle) if subtitle.present?
  return header.html_safe
end

It works, but it's ugly and I know there is a better way, I just can't find it.

Upvotes: 0

Views: 995

Answers (2)

iain
iain

Reputation: 16274

I'd go for a partial.

app/views/shared/_page_header.html.erb:

<% if title.present? %>
  <h1><%= title %></h1>
<% end %>

<% if subtitle.present? %>
  <h3><%= subtitle %></h3>
<% end %>

And the helper would be:

def page_header(title = nil, subtitle = nil)
  render "shared/page_header", :title => title, :subtitle => subtitle
end

You can also look at cells.

Upvotes: 2

Chris Heald
Chris Heald

Reputation: 62648

I'd try something like:

def page_header(title=nil, subtitle=nil)
  [
    title && content_tag(:h1, title),
    subtitle && content_tag(:h3, subtitle)
  ].join.html_safe
end

While not technically equivalent - that'll include the tags even if the title is not-nil but blank - it'll probably do what you want in this case.

If you want to get fancy:

MAPPINGS = [[:title, "h1"], [:subtitle, "h3"]]
def page_header(options = {})
  MAPPINGS.map {|e| options[e[0]] && content_tag(e[1], options[e[0]]) }.join.html_safe
end

Then, you can call:

page_header :title => "Foobar", :subtitle => "Woohoo"

And it'll work. I'd argue that the second helper is uglier though.

Upvotes: 1

Related Questions