Задача: усі маршрути мають префікс {locale} чи {team}:
Route::prefix('{locale}')->group(function () {
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{post}', [PostController::class, 'show'])->name('posts.show');
});
Тепер кожен виклик route() вимагає locale: route('posts.show', ['locale' => app()->getLocale(), 'post' => $post]). Забули - виняток Missing required parameter. Посилань сотні.
URL::defaults - значення параметра за замовчуванням на весь запит:
final class SetUrlDefaults
{
public function handle(Request $request, Closure $next): Response
{
URL::defaults(['locale' => $request->route('locale') ?? config('app.locale')]);
return $next($request);
}
}
Далі просто route('posts.show', $post) - locale підставиться сам.
Пастка з прив'язкою моделей. Якщо маршрут використовує неявну прив'язку моделей ({post}), middleware SubstituteBindings будує й перевіряє параметри маршруту. Якщо ваш middleware зі значеннями за замовчуванням виконується після нього, прив'язка спрацює раніше, ніж з'являться значення, - і ви отримаєте помилки на кшталт неправильних параметрів. Тому middleware ставлять у пріоритеті перед SubstituteBindings:
->withMiddleware(function (Middleware $middleware): void {
$middleware->prependToPriorityList(
before: \Illuminate\Routing\Middleware\SubstituteBindings::class,
prepend: \App\Http\Middleware\SetUrlDefaults::class,
);
})
Де ще потрібні значення за замовчуванням:
- черги, команди, листи - там немає поточного запиту й middleware не виконується. Завдання, яке генерує посилання для листа, має встановити
URL::defaultsсаме (наприклад, з локалі отримувача) - інакше зновуMissing required parameter; - Octane: значення за замовчуванням зберігаються в генераторі URL між запитами в тому самому воркері, тож middleware має встановлювати їх на кожен запит, а не лише коли значення змінилося;
- тести: у тестах генерації посилань поза HTTP-запитом значення треба задати явно.
Альтернативи:
- субдомени (
{team}.app.com) - те саме з параметром домену вRoute::domain('{team}.example.com'); - локаль без префікса URL (з налаштувань користувача чи заголовка) - простіше для маршрутів, але гірше для SEO і кешування: одна адреса з різним вмістом.