Automatic body tag id with Rails

Sometimes you want to style a certain page (or a certain element of a certain page) differently than others. The easiest way to do that is to give a unique id to the body tag.

In your stylesheet you say something like:

body#my-unique-id a.rule {
  background-color: #f00;
}

Which, of course, makes that particular selector only apply to one page. As with everything, this is really easy to do in Rails. You can put something like this in application_helper.rb:

def bodytag_id
  a = controller.class.to_s.underscore.gsub(/_controller$/, '')
  b = controller.action_name.underscore
  "#{a}-#{b}".gsub(/_/, '-')
end

It simply takes the current controller and action, say MyController#the_action and converts id to my-controller-the-action. I prefer dashes in class names and id's. Personal preference.

Call it in your layout:

<body id="<%= bodytag_id %>" class="standard">

I like to give each layout a unique class name as well, to differentiate them in the same kind of way. Now every page on your site has the hooks necessary to customize its style.

There are 4 comments

  1. About 9 hours later, majman said...

    very cool - keeep it coming

  2. 1 day later, joshua said...

    Thanks, I hadn't gotten around to implementing that in my app yet, but I wanted to set my body id to the controller and set the class on my wrapper div to the action so I could style them separately (e.g. style all pages from the user controller, or style all pages with the edit action)

    def body_id controller.class.tos.underscore.gsub(/controller$/, '').gsub(/_/, '-') end

    def wrapper_class controller.actionname.underscore.gsub(//, '-') end

  3. 13 days later, Blaine Cook said...

    Very clever trick. I'm wondering though if there might be some security implications with doing this. I mean, there shouldn't be, but you never know, especially with routes. In any event, I wonder if an MD5 sum of the controller / action might be useful in lieu of exposing that level of detail?

  4. 14 days later, Ryan said...

    What security risk(s) do you see? I don't see anything beyond that your controller and action names are exposed - but that's no different than if you use default routes. An MD5 has would certainly hide it but would be incredibly hard to use in you stylesheet..