larakit/lk-route

[Larakit] Управление роутами

1.0.0 2016-06-14 17:17 UTC

This package is auto-updated.

Last update: 2024-10-16 01:07:13 UTC


README

Total Downloads Latest Stable Version Latest Unstable Version License

[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

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3333652f3036362f6536342f33336530363665363465633834626361393061656637653165613731333138652e706e67

Создадим контроллер "App\Http\Controllers\AboutController" и запустим команду php artisan route:list еще раз:

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3732302f3332332f3363652f37323033323333636530363434303064386561323032323966643430613934362e706e67

Все хорошо, но мы хотим, чтобы эта страница была доступна только методом GET

###Ограничим доступные методы

\Larakit\Route\Route::item('about')
    ->put('get');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3362652f3034612f3166632f33626530346131666338656334636565626466396637353965383363393535622e706e67

Заметьте, имя контроллера, пространство имен, имя метода контроллера была сгенерированы на основе имени роута автоматически, но это можно изменить.

###Изменение пространства имен По умолчанию, пространство имен берется из App::getNamespace(). Но его можно изменить на уровне группы:

\Larakit\Route\Route::item('about')
    ->setNamespace('Qwerty')
    ->put('get');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f6639622f3533652f3366622f66396235336533666233316534386462613038613763666133336565383436372e706e67

Из полученного исключения сразу понятно, какое пространство имен контроллера ожидалось - создаем его и все работает.

###Изменение имени контроллера

\Larakit\Route\Route::item('about')
    ->setNamespace('Qwerty')
    ->setController('AboutPage')
    ->put('get');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f6632372f3537652f6330372f66323735376563303731613134336266626233363561633362323463306464342e706e67

Так же можно задать callback

\Larakit\Route\Route::item('about')
    ->setUses(function(){
        return 'Callback Text!';
    })
    ->put('get');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f6632652f3764662f6666642f66326537646666666465643634373063396234353964626263363736346533652e706e67

###Изменение домена Если у вас на одном проекте работают много доменов, например

habrahabr.ru
<username>.habrahabr.ru

то можно сделать так, чтобы роут был доступен только на одном домене

\Larakit\Route\Route::item('about')
    ->setDomain('habrahabr.ru')
    ->setUses(function(){
        return 'Callback Text!';
    })
    ->put('get');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3062352f6361392f6233652f30623563613962336534623734363862396637373935353232346438386166622e706e67

или так:

\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');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f6561352f6332642f3366372f65613563326433663733376334353733623138653564656364306564633330372e706e67

###Создание группы связанных роутов Попытаемся сделать связку роутов для админки, которые будут заниматься управлением пользователями В итоге должна получиться такая структура

/admincp/users/
/admincp/users/add/
/admincp/users/123/
/admincp/users/123/edit
/admincp/users/123/delete

Рекомендация: разбивайте имя роута точками по слэшам

\Larakit\Route\Route::item('admin.users')
    //добавим страницу со списком пользователей
    ->put();

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3930302f6366382f3730332f39303063663837303332356234646236623135343966346464333635663564372e706e67

Видим, что автоматически сформированный URL нас не устраивает, поправим его (он автоматически поменяется для всех вложенных в группу страниц)

$group = \Larakit\Route\Route::item('admin.users')
    //изменим базовый URL
    ->setBaseUrl('admincp/users');

#/admincp/users/
$group->put();

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3363362f3236332f6665362f33633632363366653662643634313435623436653036626533353235653238342e706e67

Зарегистрируем страницу добавления пользователя

$group = \Larakit\Route\Route::item('admin.users')
    //изменим базовый URL
    ->setBaseUrl('admincp/users');

#/admincp/users/
$group->put();

#/admincp/users/add
$group
    ->addSegment('add')
    ->put();

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3535642f6635652f3631342f35356466356536313438653634323262396639663333653432326666383830352e706e67

Сделаем так, чтобы у нас при запросе на этот роут методом 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');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3735612f3664642f3636302f37356136646436363066663934356461396336623438616139306366373365652e706e67

Продолжаем! Добавим вывод страницы пользователя

$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');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3835372f3438392f3730632f38353734383937306362343334383464383032366633353466333264306661652e706e67

Причем, автоматически будет произведена проверка, что параметр 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');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3264312f3230372f3332372f32643132303733323762326534313537396238313337663939393236643565662e706e67

###Роуты с параметрами

Сделаем роут для перехода из контекстной рекламы по ссылке с 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();

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3365332f6438362f6635662f33653364383666356666373034346532396538356336393732313630326565372e706e67

###Роуты с расширением Для того, чтобы сделать роут 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');

68747470733a2f2f686162726173746f726167652e6f72672f66696c65732f3537372f3163612f6664632f35373731636166646361333734356537616134333837353435323965356263322e706e67

Вот так легко и непринужденно мы добились всех поставленных целей и избавились от необходимости держать в голове принцип построения роутинга в Laravel5