in Laravel, Our Authors

Laravel Blade directive for conditional HTML classes

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