0

I'm trying to auto generate page headings by path and currently I have this in my application_helper. The method works but is there a simpler way to write this?

def page_headings
  if current_page? about_path
    "about"
  elsif
    current_page? members_path
      "members"
  elsif
    current_page? sponsors_path
      "sponsors"
  elsif
    current_page? events_path
      "events"
  elsif
    current_page? membership_path
      "join us"
  elsif
    current_page? womens_path
      "women's page"
  elsif
    current_page? new_session_path
      "log in"
  elsif
    current_page? new_user_path
      "register"
  end
end

Then, in my partial, I add this:

<%= page_headings.upcase %>
Dave Powers
  • 2,051
  • 2
  • 30
  • 34
  • Are you trying to set the page title using an HTML title tag? Or are you simply rendering this text to the page? Also, are these actions all part of the same controller? – Dave Powers Mar 12 '19 at 19:27
  • Looks like a classic [switch case](https://stackoverflow.com/questions/948135/how-to-write-a-switch-statement-in-ruby) – Guy Yogev Mar 12 '19 at 19:48
  • @DavePowers I'm trying to utilize DRY in my HTML code so I want to render the text to the page. All the actions are in different controllers, that's why I put my method in application_helper. – Caroline Nguyen Mar 12 '19 at 21:01

1 Answers1

0

A more compact way would be with a case statement:

def current_path
  request.env['PATH_INFO']
end

def page_headings
  case current_path
  when about_path then "about"
  when members_path then "members"
  when sponsors_path then "sponsors"
  when events_path then "events"
  when membership_path then "join us"
  when womens_path then "women's page"
  when new_session_path then "log in"
  when new_user_path then "register"
  else
    puts "PAGE TITLE MISSING" if Rails.env.development?
    "My App Name"
  end
end

However a common pattern for this in Rails is to consider the title as part of the view layer, and use provide and yield from your views like this:

# app/layouts/application.html.erb
<title><%= yield(:title) + ' | ' if content_for?(:title) %>My App</title>

# app/views/about/index.html.erb
<% provide(:title, "About") %>
<h1>About</h1>

# app/views/sponsors/index.html.erb
<% provide(:title, "Sponsored by #{@sponsor.name}") %>
<h1>Sponsored by <%= @sponsor.name %></h1>

The upside of the case statement is it's easy to keep everything all in one place, but the downside is that it's far away from where you actually define what a page looks like, and could potentially use content from instance variables in the title.

Unixmonkey
  • 18,485
  • 7
  • 55
  • 78
  • This won't work as written. The [`current_page?` method](https://apidock.com/rails/ActionView/Helpers/UrlHelper/current_page%3f) is missing a required argument. – Dave Powers Mar 12 '19 at 20:49
  • 1
    @DavePowers Thanks for spotting that. I've made an edit to use `current_path` instead. Funny how both answers missed the same thing. – Unixmonkey Mar 12 '19 at 21:13
  • @Unixmonkey I keep getting an `undefined local variable or method 'current_path'` error using `case current_path`. Tried a couple different combos and nothing's worked so far. – Caroline Nguyen Mar 12 '19 at 22:55
  • @CarolineNguyen Sorry, I forgot that `current_path` isn't built-in to Rails. I've edited the answer with a simple implementation that should work for you. – Unixmonkey Mar 12 '19 at 23:34
  • Works perfectly! Thank you so much! – Caroline Nguyen Mar 12 '19 at 23:40