larakit / lk-route
[Larakit] Управление роутами
Requires
This package is auto-updated.
Last update: 2024-12-16 01:35:46 UTC
README
[LarakitRoute]
Проблема, которые решает данный инструмент:
- не надо держать в голове структуру формирования роутов и групп за счет использования автодополнения кода в IDE
Массивы - это удобно и просто. Но каждый раз лезти в документацию - это потери рабочего времени
Route::group(['middleware' => 'auth'], function () { Route::get('/', function () { // Uses Auth Middleware }); Route::get('user/profile', function () { // Uses Auth Middleware }); });
Рассмотрим типовые потребности, которые легко и красиво реализовывает данный пакет
###Обычная страница "О нас" Добавим роут в ./app/Http/routes.php
\Larakit\Route\Route::item('about') ->put();
Посмотрим список роутов в консоли:
php artisan route:list
Создадим контроллер "App\Http\Controllers\AboutController" и запустим команду php artisan route:list еще раз:
Все хорошо, но мы хотим, чтобы эта страница была доступна только методом GET
###Ограничим доступные методы
\Larakit\Route\Route::item('about') ->put('get');
Заметьте, имя контроллера, пространство имен, имя метода контроллера была сгенерированы на основе имени роута автоматически, но это можно изменить.
###Изменение пространства имен По умолчанию, пространство имен берется из App::getNamespace(). Но его можно изменить на уровне группы:
\Larakit\Route\Route::item('about') ->setNamespace('Qwerty') ->put('get');
Из полученного исключения сразу понятно, какое пространство имен контроллера ожидалось - создаем его и все работает.
###Изменение имени контроллера
\Larakit\Route\Route::item('about') ->setNamespace('Qwerty') ->setController('AboutPage') ->put('get');
Так же можно задать callback
\Larakit\Route\Route::item('about') ->setUses(function(){ return 'Callback Text!'; }) ->put('get');
###Изменение домена Если у вас на одном проекте работают много доменов, например
habrahabr.ru
<username>.habrahabr.ru
то можно сделать так, чтобы роут был доступен только на одном домене
\Larakit\Route\Route::item('about') ->setDomain('habrahabr.ru') ->setUses(function(){ return 'Callback Text!'; }) ->put('get');
или так:
\Larakit\Route\Route::item('about') ->setDomain('*.habrahabr.ru') ->setUses(function(){ return 'Callback Text!'; }) ->put('get'); \Larakit\Route\Route::item('about_groove') ->setDomain('groove.habrahabr.ru') ->setUses(function(){ return 'About Groove!'; }) ->put('get');
###Создание группы связанных роутов Попытаемся сделать связку роутов для админки, которые будут заниматься управлением пользователями В итоге должна получиться такая структура
/admincp/users/
/admincp/users/add/
/admincp/users/123/
/admincp/users/123/edit
/admincp/users/123/delete
Рекомендация: разбивайте имя роута точками по слэшам
\Larakit\Route\Route::item('admin.users') //добавим страницу со списком пользователей ->put();
Видим, что автоматически сформированный URL нас не устраивает, поправим его (он автоматически поменяется для всех вложенных в группу страниц)
$group = \Larakit\Route\Route::item('admin.users') //изменим базовый URL ->setBaseUrl('admincp/users'); #/admincp/users/ $group->put();
Зарегистрируем страницу добавления пользователя
$group = \Larakit\Route\Route::item('admin.users') //изменим базовый URL ->setBaseUrl('admincp/users'); #/admincp/users/ $group->put(); #/admincp/users/add $group ->addSegment('add') ->put();
Сделаем так, чтобы у нас при запросе на этот роут методом GET отдавалась страница с формой добавления пользователя, а при запросе методом POST производилась попытка валидации и сохранения пользователя.
Причем, чтобы этот функционал был разнесен по разным методам контроллера.
$group = \Larakit\Route\Route::item('admin.users') //изменим базовый URL ->setBaseUrl('admincp/users'); #/admincp/users/ $group->put(); #/admincp/users/add $group ->addSegment('add') ->setAction('create') ->put('get') ->addSegment('add') ->setAction('store') ->put('post');
Продолжаем! Добавим вывод страницы пользователя
$group = \Larakit\Route\Route::item('admin.users') //изменим базовый URL ->setBaseUrl('admincp/users'); #/admincp/users/ $group->put(); #/admincp/users/add $group ->addSegment('add') ->setAction('create') ->put('get') ->addSegment('add') ->setAction('store') ->put('post'); #/admincp/users/{user_id} $group //сделаем сброс добавленного сегмента "add" чтобы начать формировать новую ветку от базового URL ->clearSegments() ->addSegment('{user_id}') //зададим паттерн для этого параметра только этого роута //->addPattern('user_id', '[a-z0-9]+') //true означает проверку на целое число (как самое часто употребляемое) ->addPattern('user_id', true) ->put('get');
Причем, автоматически будет произведена проверка, что параметр id является целым числом
Но нам хотелось бы, чтобы производилась проверка на наличие модели с таким идентификатором. Для этого на уровне группы добавим модель и опишем ее.
//проверка на наличие пользователя с таким идентификатором Route::model('user_id', \App\User::class, function ($id) { throw new \Illuminate\Database\Eloquent\ModelNotFoundException('User with ID='.$id.' not found!'); }); $group = \Larakit\Route\Route::item('admin.users') //изменим базовый URL ->setBaseUrl('admincp/users'); #/admincp/users/ $group->put(); #/admincp/users/add $group ->addSegment('add') ->setAction('create') ->put('get') ->addSegment('add') ->setAction('store') ->put('post'); #/admincp/users/{user_id} $group //сделаем сброс последнего добавленного сегмента "add" чтобы начать формировать новую ветку от /admincp/users/ ->popSegment() ->addSegment('{user_id}') //зададим паттерн для этого параметра только этого роута //->addPattern('user_id', '[a-z0-9]+') ->addPattern('user_id', true) ->put('get');
Добавим оставшиеся методы
//проверка на наличие пользователя с таким идентификатором Route::model('user_id', \App\User::class, function ($id) { throw new \Illuminate\Database\Eloquent\ModelNotFoundException('User with ID='.$id.' not found!'); }); $group = \Larakit\Route\Route::item('admin.users') //изменим базовый URL ->setBaseUrl('admincp/users'); #/admincp/users/ $group->put(); #/admincp/users/add $group ->addSegment('add') ->setAction('create') ->put('get') ->addSegment('add') ->setAction('store') ->put('post'); #/admincp/users/{user_id} $group //сделаем сброс последнего добавленного сегмента "add" чтобы начать формировать новую ветку от /admincp/users/ ->popSegment() ->addSegment('{user_id}') //зададим паттерн для этого параметра только этого роута //->addPattern('user_id', '[a-z0-9]+') ->addPattern('user_id', true) ->put('get'); #/admincp/users/{user_id}/edit $group ->addSegment('edit') ->setAction('update') ->put('get') ->addSegment('edit') ->setAction('store') ->put('post'); #/admincp/users/{user_id}/delete $group //сделаем сброс последнего добавленного сегмента "edit" чтобы начать формировать новую ветку от /admincp/users/{user_id}/ ->popSegment() ->addSegment('delete') ->put('delete');
###Роуты с параметрами
Сделаем роут для перехода из контекстной рекламы по ссылке с UTM-метками.
При добавлении параметров роута следующие правила:
- сперва передаем имя параметра, если он не обязателен - добавьте после него вопрос, например 'param_name?'
- затем передаем правило валидации (регулярное выражение)
/{utm_source}/{utm_medium}/{utm_campaign}/{utm_term}/{utm_content}
$group = \Larakit\Route\Route::item('utm') ->setController('Utm') //Источник кампании - utm_source //Источник перехода: google, yandex, newsletter и т.п. ->addSegment('{utm_source}') ->addPattern('utm_source', '(google|yandex|newsletter)') //Канал кампании - utm_medium //Тип трафика: cpc, ppc, banner, email и т.п. ->addSegment('{utm_medium}') ->addPattern('utm_medium', '[\w-\d]+') //Название кампании - utm_campaign //впишем сюда ID компании из местной CRM (целое число) //можно было вручную вписать "'[0-9]+'", но "true" короче и чаще всего используется ->addSegment('{utm_campaign}') ->addPattern('utm_campaign', true) //Ключевое слово - utm_term //(не обязательное поле, без валидации) ->addSegment('{utm_term?}') //Содержание кампании - utm_content //(не обязательное поле, без валидации) ->addSegment('{utm_content?}') ->put();
###Роуты с расширением Для того, чтобы сделать роут about.html и data.json нужно в метод put() вторым, необязательным параметром передать расширение
\Larakit\Route\Route::item('about') ->put('get', 'html'); \Larakit\Route\Route::item('data') ->setUses(function(){ return [ [ 'name' => 'Toyota', ], [ 'name' => 'Nissan', ], ]; }) ->put('get', 'json');
Вот так легко и непринужденно мы добились всех поставленных целей и избавились от необходимости держать в голове принцип построения роутинга в Laravel5