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

This blog post follows up on the first overview of the new Blade, Requests, Routing and Validation features in Laravel 8 since the original release in September 2020. Enjoy!

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

Requests and Routing

v8.65.0 Added Subset in request's collect (#39191)

The collect method now allows you to get a subset.

$request->collect(['email', 'roles'])->all();
 
// [
// 'email' => '[email protected]',
// 'roles' => [1, 2, 3]
// ];

v8.70.0 Allow can method to be chained onto route for quick authorization (#39464)

For convenience, you may attach the can middleware to your route using the can method:

// Before:
Route::put('/post/{post}', UpdatePost::class)->middleware('can:update,post');
 
// After:
Route::put('/post/{post}', UpdatePost::class)->can('update', 'post');

v8.77.1 Added datetime parsing to Request instance (#39945)

Retrieve input from the request as a Carbon instance.

// Before:
if ($birthday = $request->input('birthday')) {
$birthday = Carbon::parse($birthday);
}
 
// After:
$birthday = $request->date('birthday');
 
// With format and timezone:
$elapsed = $request->date('elapsed', '!H:i', 'Europe/Madrid');

v8.78.0 Added a mergeIfMissing method to the Illuminate Http Request class (#40116)

Merge new input into the request's input, but only when that key is missing from the request.

// Before:
if ($request->missing('boolean_setting')) {
$request->merge(['boolean_setting' => 0]);
}
 
// After:
$request->mergeIfMissing(['boolean_setting' => 0])

v8.80.0 Added support for specifying a route group controller (#40276)

If a group of routes all utilize the same controller, you may now use the controller method to define the common controller for all of the routes within the group.

// Before:
Route::prefix('placements')->as('placements.')->group(function () {
Route::get('', [PlacementController::class, 'index'])->name('index');
Route::get('/bills', [PlacementController::class, 'bills'])->name('bills');
Route::get('/bills/{bill}/invoice/pdf', [PlacementController::class, 'invoice'])->name('pdf.invoice');
});
 
// After:
Route::controller(PlacementController::class)->prefix('placements')->as('placements.')->group(function () {
Route::get('', 'index')->name('index');
Route::get('/bills', 'bills')->name('bills');
Route::get('/bills/{bill}/invoice/pdf', 'invoice')->name('pdf.invoice');
});

Blade Templates

v8.71.0 Introduce @js() directive (#39522) + Introduce Js for encoding data to use in JavaScript (#39389, #39460)

For years we had the @json Blade directive to avoid manually calling json_encode, but now there's a replacement to handle more cases: @js. It handles objects, arrays and strings, else, falls back to json_encode.

<div x-data="@js($data)"></div>

v8.80.0 Added a BladeCompiler::render() method to render a string with Blade (#40425)

This new method allows you to call render and get the string with all the Blade compiled returned.

Blade::render('Hello, {{ $name }}', ['name' => 'Claire']);
 
// Returns 'Hello, Claire'

Validation

v8.65.0 Added ability to validate one of multiple date formats (#39170)

This PR adds the ability to provide multiple possible date formats to the date_format validation rule, allowing developers to use one request input for multiple possible date format types.

Validator::validate([
'dates' => ['2021-12-01', '12-01'],
], [
'dates.*' => 'date_format:Y-m-d,m-d',
]);

v8.69.0 Added an Enum validation rule (#39437)

This PR adds a new Enum validation rule that will make sure the provided data has a corresponding case in the enum.

Validator::validate([
'status' => 'pending'
], [
'status' => [new Enum(ServerStatus::class)]
]);

v8.71.0 Added declined and declined_if validation rules (#39579)

Reverse off the accepted and accepted_if rules. The field under validation must be "no", "off", 0, or false.

Validator::validate([
'foo' => 'off'
], [
'foo' => 'declined'
]);

v8.77.1 Added rule to validate MAC address (#40098)

A new validation rule to ensure that the attribute is a valid MAC address.

Validator::validate([
'mac' => '01-23-45-67-89-ab'
], [
'mac' => 'mac_address'
]);

v8.73.0 Added Prohibits validation rule to dependentRules property (#39677)

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

Validator::validate([
'users' => [
['email' => 'foo', 'emails' => 'foo'],
['emails' => 'foo'],
],
], [
'users.*.email' => 'prohibits:users.*.emails',
]);

v8.78.0 Added ability to define extra default password rules (#40137)

Specify the default validation rules for passwords in a single location of your application.

Password::defaults(function () {
$rule = Password::min(8);
 
return $this->app->isProduction()
? $rule->mixedCase()->uncompromised()
: $rule;
});