3

My application.html.erb file looks like this

<!DOCTYPE html>
<html lang="en">
  <head>
  .
  .
  .
  </head>
  <body <%= "class=landing-bg" if !@landing.nil? %>>
    <%= render 'layouts/header' %>
    <div class="container">
    .
    .
    .
    </div>
    <%= render 'layouts/footer' %>
    <% if !@landing.nil? %>
      <div class="landing-gradient"></div>
    <% end %>
  </body>
</html>

I've left out a bunch of meta tags in the <head> and a bunch of other code in the body that's unrelated to the question.

static_pages_controller

def home
  @landing = "landing"
end

I need to add a class to <body> and a div below the footer only on my home page. I feel like what I am doing is a bit hacky. And, if I created a separate layout just for the landing page it wouldn't be DRY since I would be repeating alot of code that's on this layout.

What is the best way to do this? What is the rails way?

user4584963
  • 2,403
  • 7
  • 30
  • 62

3 Answers3

7

My typical pattern is to add the controller and action into the class of the body, and then use those as selectors in my css like this:

<body class="<%= controller_name %> <%= action_name %>">
  <!-- etc -->
</body>

As for your second issue of a conditionally body on only the home page, you can simply add that into the body in the main layout and display it only on the landing page:

<body class="<%= controller_name %> <%= action_name %>">
  <!-- etc -->
  <div class="landing-gradient"></div>
</body>

# application.css
.landing-gradient {
  display: none;               // Hide the gradient
}

.landing .landing-gradient {
   display: inline;            // Show gradient b/c of more specific selector
}

This is my personal preference since you're leaving display of individual elements to the css / presentation layer instead of within your controllers.

Finally, you could also use a content_for around the footer so that you can customize the footer across individual pages. That's a bit heavy handed for your example though, so I'd only use that if you were customizing the footer a lot.

Community
  • 1
  • 1
Gavin Miller
  • 43,168
  • 21
  • 122
  • 188
3

In my case I want to have a different class per layout (at least potentially), so in app/views/layouts/application.html.erb I do this:

<body class="<%= yield(:body_class) %>">

and then in my layout file I do this:

<% content_for(:body_class) { 'my-class' } %>
Jason Swett
  • 43,526
  • 67
  • 220
  • 351
1

You can also manage it without creating an instance variable and verifying it in your view but using the params[:action] and params[:controller]:

<body class="<% 'class_value' if params[:controller] == 'static_pages' && params[:action] == 'home' %>"

You can just validate for the action (method) if you don't have more than one home method.

Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59