views:

114

answers:

1

In every webapp I build, I come across this issue. I want to set classes on HTML elements conditionally. For example, sometimes the <div> for a post looks like:

<div class="post">...</div>

And sometimes it looks like this:

<div class="post even recent replied_to author_is_admin">...</div>

Each class after post is there because some logic decided it should be. What is the best way to this? In Rails+HAML, I've been guilty of doing stuff like:

-classes = []
-classes << cycle('even', 'odd')
-classes << 'recent' if post.recent?
-classes << 'replied_to' if post.replied_to?
-classes << 'author_is_admin' if post.author_is_admin?
.post{:class => classes.join(' ')}
    ...

It's not pretty, and I've shortened it to use a helper so I can do this:

.post{:class => "#{cycle('even', 'odd')} #{post_classes}"}

It still seems like it should be easier to read, because it's something we do all the time. Does you have any methods by which you make this process short and readable?

+1  A: 

I think what you've done is fine. I would only suggest a few minor improvements. One would be to put the cycle call in post_classes. For readability, I would make post_classes accept Post argument. This creates a little redundancy, but you can easily avoid it by defining this helper method:

def classes(object)
  case object
  when Post then post_classes(object)
  end
end

That way, your template code will look like this:

.post{:class => classes(Post)}
allyourcode