Blade, Requests, Routing, and Validation: New features since the Laravel 8.0 release in September 2020 (1/2)

Following last week's blog post about Jobs and Queues, here's an overview of new features and improvements when it comes to Blade, Requests, Routing and Validation.

I got most code examples and explanations from the PRs and official documentation.

Requests and Routing

v8.17.0 Added dd() and dump() to the request object (#35384)

Quickly inspect the request input.

public function index(Request $request)
{
// before:
dd($request->all());
// after:
$request->dd();
$request->dd(['name', 'age']);
$request->dd('name', 'age');
}

v8.26.0 Added Route::missing() (#36035)

Typically, a 404 HTTP response will be generated if an implicitly bound resource model is not found. With the missing method you may change this behavior:

Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
->name('locations.view')
->missing(fn($request) => Redirect::route('locations.index', null, 301));

v8.55.0 Added Support withTrashed on routes (#38348)

This allows you to specify a single route that allows soft deleted models when resolving implicit model bindings:

Route::post('/user/{user}', function (ImplicitBindingModel $user) {
return $user;
})->middleware(['web'])->withTrashed();

v8.56.0 Added fullUrlWithoutQuery method to Request (#38482)

Get the full URL for the request without the given query string parameters.

// When the current URL is
// https://example.com/?color=red&shape=square&size=small
request()->fullUrlWithoutQuery('color');
// https://example.com/?shape=square&size=small
request()->fullUrlWithoutQuery(['color', 'size']);
// https://example.com/?shape=square

Blade Templates

v8.19.0 Added Illuminate\View\ComponentAttributeBag::has() (#35562)

Allows to determine if a given attribute is present on a component.

@if ($attributes->has('class'))
<div>Class Attribute Present</div>
@endif

v8.27.0 Conditionally merge classes into a Blade Component attribute bag (#36131)

Inspired by Vue's :class syntax, this PR adds a class() method to the ComponentAttributeBag class. It merges the given classes into the attribute bag.

<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}>

As of v8.51, you can use the class directive as well:

<div @class(['p-4', 'bg-red' => $hasError])>

v8.45.0 Adds class handling for Blade echo statements (#37478)

This PR adds a new Blade::stringable() method that allows the user to add intercepting closures for any class. The returned value will be outputted in Blade.

// AppServiceProvider
Blade::stringable(Money::class, fn($object) => $object->formatTo('en_GB'));
Blade::stringable(Carbon::class, fn($object) => $object->format('d/m/Y')));
<dl>
<dt>Total</dt>
<dd>{{ $product->total }}</dd> <!-- This is a money object, but will be outputted as an en_GB formatted string -->
<dt>Created at</dt>
<dd>{{ $product->created_at }}</dd> <!-- This is a Carbon object, but will be outputted as English date format -->
</dl>

v8.64.0 Added @aware blade directive (#39100)

You may use the @aware directive to access data from a parent component inside a child component. For example, imagine a parent <x-menu> and child <x-menu.item>:

<x-menu color="purple">
<x-menu.item>...</x-menu.item>
<x-menu.item>...</x-menu.item>
</x-menu>

By using the @aware directive, you can make the color prop available inside <x-menu.item> as well:

<!-- /resources/views/components/menu/item.blade.php -->
@aware(['color' => 'gray'])
<li {{ $attributes->merge(['class' => 'text-'.$color.'-800']) }}>
{{ $slot }}
</li>

Validation

v8.32.0 Added prohibited_if and prohibited_unless validation rules (#36516)

The field under validation must be empty or not present if the anotherfield field is equal to any value.

Validator::validate([
'is_deceased' => false,
'date_of_death' => '2021-01-01'
], [
'date_of_death' => 'prohibited_unless:is_deceased,true'
]);

v8.34.0 Added prohibited validation rule (#36667)

The field under validation must be empty or not present.

Validator::validate([
'name' => 'hello-world',
'key' => 'random-key',
], [
'name' => 'required|max:255',
'key' => 'prohibited',
]);

v8.39.0 Added password validation rule (#36960)

To ensure that passwords have an adequate level of complexity, you may use Laravel's Password rule object:

Validator::validate([
'password' => '123123',
], [
'password' => ['required', 'confirmed', Password::min(8)
->mixedCase()
->letters()
->numbers()
->symbols()
->uncompromised(),
],
]);

v8.47.0 Copy password rule to current_password (#37650)

To prevent communication problems with the new Password rule object, the password rule was renamed to current_password with the intention of removing it in Laravel 9.

v8.52.0 Added Unique::withoutTrashed() (#38124)

This PR adds a helper method to the unique validation rule for working with models which can be soft deleted.

// Before
Rule::unique('users')->whereNull('deleted_at');
// After
Rule::unique('users')->withoutTrashed();

v8.54.0 Added withoutTrashed on Exists rule (#38314)

In addition to the unique rule in the example above, you may also use the withoutTrashed method on the exists rule.

// Before
Rule::exists('users')->whereNull('deleted_at');
// After
Rule::exists('users')->withoutTrashed();

v8.53.0 Added accepted_if validation rule (#38210)

In addition to the accepted rule, you can now use this rule if another field under validation is equal to a specified value.

Validator::validate([
'newsletter_subscription' => '1',
'newsletter_terms' => '0',
], [
'newsletter_subscription' => 'required|boolean',
'newsletter_terms' => 'accepted_if:newsletter_subscription,1',
]);

v8.57.0 Added exclude validation rule (#38537)

The field under validation will be excluded from the request data returned by the validate and validated methods. There are exclude_if, exclude_unless, and exclude_without rules as well.

Validator::validate([
'role' => 'guest',
'email' => '[email protected]',
], [
'role' => ['required', 'in:user,guest'],
'email' => ['required_if:role,user', 'exclude_unless:role:user', 'email'],
]);

v8.58.0 Added prohibits validation (#38612)

If the field under validation is present, no fields in anotherfield can be present, even if empty.

Validator::validate([
'email' => '[email protected]',
], [
'email' => 'prohibits:emails'
]);

v8.55.0 Added Conditional rules (#38361)

You may use Rule::when() to create a new conditional rule set.

Validator::validate([
'password' => '123456',
], [
'password' => ['required', 'string', Rule::when(true, ['min:5', 'confirmed'])],
]);

v8.55.0 Added Validated subsets (#38366)

You may now retrieve a portion of the validated input data:

$validator->safe()->only(['name', 'email']);
$validator->safe()->except([...]);

This works on Form Requests as well:

$formRequest->safe()->only([...]);
$formRequest->safe()->except([...]);