Sheath rule
blade-prefer-unless
Prefer
@unless over @if(!...) for negative conditions.
#Why
@unless ($user->hasVerifiedEmail()) expresses a negated condition without a
leading !.
@unless wraps its condition before negating it, so @unless ($a && $b)
compiles to if (! ($a && $b)). A hand-written @if (! $a && $b) compiles to
if (! $a && $b), which negates only $a.
This is a stylistic preference, so it belongs to stylistic rather than
recommended.
#Examples
#Bad
<!-- Negated conditions with @if -->
@if(!$user->isAdmin())
<p>You don't have admin access.</p>
@endif
@if(!$authenticated)
<a href="/login">Login</a>
@endif
@if(!count($items))
<p>Your cart is empty.</p>
@endif
@if(!$post->published)
<span class="badge">Draft</span>
@endif
#Good
<!-- Cleaner with @unless -->
@unless($user->isAdmin())
<p>You don't have admin access.</p>
@endunless
@unless($authenticated)
<a href="/login">Login</a>
@endunless
@unless(count($items))
<p>Your cart is empty.</p>
@endunless
@unless($post->published)
<span class="badge">Draft</span>
@endunless
<!-- @if is fine for positive conditions -->
@if($user->isAdmin())
<a href="/admin">Admin Panel</a>
@endif
<!-- A negation that covers only part of the condition stays @if: rewriting
it as @unless would mean De Morgan, not deleting a character -->
@if(!$user->isBanned() && $user->isActive())
<a href="/dashboard">Dashboard</a>
@endif
@if(!$featured ? $fallback : $hero)
<img src="{{ $image }}" alt="">
@endif
#Reading Comparison
Consider how these read in English:
| Syntax | Reads as |
|---|---|
@if(!$user) |
"If not user..." (awkward) |
@unless($user) |
"Unless there's a user..." (natural) |
@if(!$authenticated) |
"If not authenticated..." |
@unless($authenticated) |
"Unless authenticated..." |
#When to Use @if vs @unless
Choose the directive that states the condition without an extra negation.
Use @if when |
Use @unless when |
|---|---|
| Positive condition | Negative condition |
@if($visible) |
@unless($hidden) |
@if($loggedIn) |
@unless($guest) |
@if($hasItems) |
@unless($isEmpty) |
#Notes
- This is a stylistic suggestion (severity: info)
- Some teams prefer consistency with
@ifeverywhere - A finding appears only when
!negates the entire condition, such as!$draftor!($a && $b). Conditions like@if (!$a && $b),!$a || $b, ternaries, and??chains are not reported because@unlesscould not take them unchanged - Complex negations may still be clearer with
@if
#Related Rules
- blade-prefer-forelse - Prefer @forelse over @if+@foreach