Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Blade Extensions Laravel Package

radic/blade-extensions

radic/blade-extensions is a collection of practical custom directives that extend Laravel's Blade templating engine. It adds convenient helpers for variable assignment, loop control, and common view tasks, letting you keep templates cleaner and more expressive without writing extra PHP.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require radic/blade-extensions

On Laravel 5.5+ the service provider (Radic\BladeExtensions\BladeExtensionsServiceProvider) is auto-discovered. On older apps, register it manually in config/app.php under providers.

Publish the config (you'll want this — many directives are toggleable and extensible):

php artisan vendor:publish --provider="Radic\BladeExtensions\BladeExtensionsServiceProvider"

Where to look first:

  • config/blade-extensions.php — this is the source of truth. It lists every directive, whether it's enabled, and where you can register your own.
  • vendor/radic/blade-extensions/src/Directives/ — each directive is a small class; skim ForeachDirective, SetDirective, ArrayDirective first.

First use case — the package's original selling point was $loop metadata inside @foreach, back before Laravel 5.3 shipped it:

@foreach($users as $user)
    <li class="{{ $loop->first ? 'first' : '' }} {{ $loop->last ? 'last' : '' }}">
        {{ $loop->iteration }}/{{ $loop->count }} — {{ $user->name }}
    </li>
@endforeach

If you're on a modern Laravel, start instead with the two directives that still have no native equivalent: @set and @array.

@set($fullName, $first . ' ' . $last)
<h1>Hello, {{ $fullName }}</h1>

Implementation Patterns

Computed locals with @set

@set lets you name intermediate values inline in a view without dropping into <?php ?>:

@set($initials, strtoupper(substr($first, 0, 1) . substr($last, 0, 1)))
<div class="avatar" data-initials="{{ $initials }}">{{ $initials }}</div>

Both @set($var, $value) and @set($var = $value) work. Prefer the comma form — it avoids compile edge cases when the value contains a = or a comparison operator.

Pair with @unset($var) to keep the shared scope clean when the value is expensive and only one partial needs it.

Multiline arrays with @array

Useful when you're passing a literal config object into an include or component and don't want to chain long array syntax into a one-liner:

@array($opts, [
    'title'  => 'Billing',
    'route'  => route('billing.index'),
    'icon'   => 'credit-card',
    'active' => request()->routeIs('billing.*'),
])

@include('partials.card', $opts)

This is much clearer than @include('partials.card', ['title' => ..., 'route' => ..., ...]) for 4+ keys, and reads like a Twig set block.

Loop control (@break / @continue)

Handy for "first N matching items" or skipping empty entries — common when rendering menus or filtered lists where you only want three hits:

@foreach($posts as $post)
    @continue(empty($post->excerpt))
    <article>{{ $post->excerpt }}</article>
    @break($loop->iteration >= 3)
@endforeach

@break and @continue accept a condition argument, so you can keep them one-line. Note these compile to break/continue inside the generated foreach, so they only work within a @foreach/@forelse block. Break out of both loops with @break(2) (n levels).

Integration with @include / @each / components

@set and @array compose well with @include:

@foreach($teams as $team)
    @set($memberCount, $team->members->count())
    @array($badge, ['text' => $memberCount . ' members', 'tone' => $memberCount > 5 ? 'ok' : 'muted'])
    @include('partials.badge', $badge)
@endforeach

You can also drop these into a <x-…> component's @props defaults, since the directives run at the Blade compile stage before the component is instantiated.

Extending with custom directives

The real long-term value is the config-driven extension point. In config/blade-extensions.php you can register a class implementing the package's DirectiveContract:

'directives' => [
    'money' => App\Blade\MoneyDirective::class,
],

Then @money($cents) compiles however you like — a clean way to add a project-specific @money/@date while still letting the package manage registration, caching, and the @end… pairing if you need it.

Gotchas and Tips

Most of it is native now

Laravel 5.3+ ships $loop (index, iteration, first, last, depth, parent, remaining, count) plus native @break, @continue. If you're on Laravel 8/9/10/11, only @set, @unset, and @array are still pulling their weight. Blindly installing this on a fresh app adds a service provider, a config file, and a directive compiler for features you already have. Audit before adopt.

Directive name collisions

If your app or another package already defines @set or @foreach (e.g. a theming package, or Livewire/Tall-stack helpers), the last registered directive wins — usually silently. Symptom: a directive you know is defined throws "unexpected end of file" or produces wrong output. Debug by dumping the compiled view (see below) and checking which path the @set compiled to. Disable the package's version in config/blade-extensions.php if you need to defer to someone else.

@set is compile-time, not runtime

@set emits a plain PHP assignment in the compiled template — it does not create a scoped variable or a view-local. Consequences:

  • It leaks out of @foreach/@if blocks (PHP has no block scope).
  • It overwrites any same-named variable passed in from the controller. Name locals defensively (@set($labelText, …), not @set($title, …)).
  • It won't be available inside a @include unless you pass it — includes have their own scope. Use @include('partial', ['x' => $x]) or @include('partial', get_defined_vars()).

Config cache

After editing config/blade-extensions.php you must run php artisan config:clear (or config:cache) — otherwise the old directive set is active in production and CI. If a directive "isn't defined" only in production, this is almost always why.

Debugging: read the compiled view

Blade compiles to storage/framework/views/. When a directive misbehaves:

php artisan view:clear
# then hit the page, and:
grep -n "some_var" storage/framework/views/*.php | tail

The compiled file shows exactly what @array/@set/@foreach emitted — the fastest way to spot a broken argument or an unexpected directive collision.

@array syntax sensitivity

The directive parses its second argument as a PHP array literal at compile time. Trailing commas, unescaped ] inside strings, or using @array($x = [...]) instead of @array($x, [...]) will produce broken PHP that only fails when the compiled view is included (a generic "syntax error, unexpected" with no line pointing at the Blade file). Keep arrays simple — no closures, no fn(), no new inside @array. For anything dynamic, compute it with @set first or use a view composer.

$loop shadowing

This package's @foreach defines its own $loop object. On Laravel 5.3+ that collides with the framework's $loop. If both are active you may see the wrong $loop->parent chain, or $loop being null inside a manually included partial that expects the native structure. Simplest fix on modern Laravel: disable the package's foreach directive entirely and keep only set/array.

Version pinning and maintenance

The package receives infrequent updates. Pin it ("radic/blade-extensions": "^2.x"), and add a test that renders each view using the directives — a snapshot/assertSee test will catch a regression the moment you bump Laravel past a Blade compiler change.

When to skip it

If your only needs are loop metadata, @break, and @continue, uninstall it and use @php/@isset/native $loop. Reserve the package for teams that lean heavily on @set/@array as a Twig-like template style, or that want the config-based custom-directive registry.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels