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
<!-- /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]',
'emails' => ['[email protected]', 'other.exa[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([...]);