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=smallrequest()->fullUrlWithoutQuery('color');// https://example.com/?shape=square&size=smallrequest()->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.
// AppServiceProviderBlade::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.
// BeforeRule::unique('users')->whereNull('deleted_at');// AfterRule::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.
// BeforeRule::exists('users')->whereNull('deleted_at');// AfterRule::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]', '[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([...]);