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!