Sometimes you need to add classes to HTML elements conditionally, and when you try to do that you almost always end up with messy syntax. Here’s the example in Blade:

<article class="post post-{{ $post->slug }} @if ($post->featured) post-featured @endif @if ($post->sticky) post-sticky @endif">
    ...
</article>

Or with pure PHP:

<article class="post post-<?php echo $post->slug ?> <?php if ($post->featured): ?>post-featured<?php endif ?> <?php if ($post->sticky): ?>post-sticky<?php endif ?>">
    ...
</article>

And if you split it into multi-line you get even worse, and when you add even more conditional classes you get if mess.

Here’s how simple Blade helper can be used to make your syntax a little simpler, it would look like this:

<article @class(['post', 'post-'.$post->slug, 'post-featured' => $post->featured, 'post-sticky' => $post->sticky])
    >
    ...
</article>

Here we have strings passed to @class directive, and conditional classes passed as key value pairs.

In key-value pairs, the value needs to be truthy  so that key/class would be added. And if you need condition like in if syntax just write it as value, like this:

<div @class(['star' => $post->stared == true])>
  ....
</div>

Here’s the function:

function html_class(array $array) {
  $classes = [];

  foreach ($array as $key => $value) {
    if (is_int($key) and $value) {
      $classes[] = $value;
    }
    else if ($value) {
      $classes[] = $key;
    }
  }

  if ($classes) {
    return 'class="'.implode(' ', $classes).'"';
  }
}

And heres how you add it to Blade:

Blade::directive('class', function($expression) {
  return '<?php echo html_class'.$expression.'; ?>';
});

Awesome!

 

Share this ...Tweet about this on TwitterShare on FacebookEmail this to someoneShare on RedditShare on Google+Share on LinkedInPin on Pinterest