Маршрутизация с именованными параметрами

У меня есть URL-адрес, содержащий именованные параметры, которые я хочу сопоставить с более удобным для пользователя URL-адресом.

Возьмем, к примеру, следующий URL:

/videos/index/sort:published/direction:desc

Я хочу сопоставить это с более удобным URL-адресом, например:

/видео/недавние

Я пытался настроить его в роутере, но он не работает.

Примеры кода от роутера:

Router::connect(
    '/videos/recent/*',
    array('controller' => 'videos', 'action' => 'index'),
    array('sort' => 'published', 'direction' => 'desc'
));

Что не работает. И следующее также не работает:

Router::connect(
    '/videos/recent/*',
    array('controller' => 'videos', 'action' => 'index', 'sort' => 'published', 'direction' => 'desc'));

Есть идеи?


person Botch    schedule 27.06.2013    source источник
comment
ты пробовал Router::connect( '/videos/recent/*', array('controller' => 'videos', 'action' => 'index'), array('pass'=>array('sort','direction'),'sort' => 'published', 'direction' => 'desc' ));??   -  person Nunser    schedule 27.06.2013
comment
Да, только что попробовал, не работает. Как и в моих примерах выше, он перенаправляется к правильному контроллеру и действию и отображает страницу, но сортировка на самом деле не работает.   -  person Botch    schedule 27.06.2013


Ответы (2)


Используйте аргументы получения

Самый простой способ заставить маршруты работать — это вообще избегать именованных аргументов. С нумерацией страниц этого легко добиться с помощью соответствующей конфигурации. :

class FoosController extends AppController {

    public $components = array(
        'Paginator' => array(
            'paramType' => 'querystring'
        )
    );
}

Таким образом, когда вы загружаете /videos/recent, вы должны обнаружить, что он включает URL-адреса в форме:

/videos/recent?page=2
/videos/recent?page=3

Вместо (из-за несоответствия маршрута)

/videos/index/sort:published/direction:desc/page:2
/videos/index/sort:published/direction:desc/page:3

Но если вы действительно хотите использовать именованные аргументы

Вам нужно будет обновить определение маршрута — в конфигурации маршрута нет страницы:

Router::connect(
    '/videos/recent/*',
    array(
        'controller' => 'videos', 
        'action' => 'index', 
        'sort' => 'published', 
        'direction' => 'desc'
     )
);

Таким образом, если есть параметр с именем страницы (который будет для всех URL-адресов, сгенерированных помощником постраничного вывода), маршрут не будет совпадать. Вы сможете исправить это, добавив page в определение маршрута:

Router::connect(
    '/videos/recent/*',
    array(
        'controller' => 'videos', 
        'action' => 'index', 
        'sort' => 'published', 
        'direction' => 'desc',
        'page' => 1
     )
);

Хотя, даже если он работает, вы можете найти его хрупким.

person AD7six    schedule 27.06.2013
comment
Второй вариант не работает. Я начинаю думать, что на самом деле нет хорошего решения для этого. Вместо этого я мог бы попробовать переданные аргументы. Спасибо. - person Botch; 27.06.2013
comment
Вам нужно будет посмотреть, например. connectNamed. Хотя, и имейте в виду, я использовал торт для ~ всегда и являюсь членом основной команды, как уже упоминалось, вам лучше просто не использовать именованные аргументы. Именованные аргументы, скорее всего, будут объявлены устаревшими и удалены в будущей (основной) версии Cake. - person AD7six; 28.06.2013

давайте посмотрим на [Документацию Router::connect] (маршруты - это способ подключения URL-адресов запросов к объектам в вашем приложении)

Маршруты — это способ подключения URL-адресов запросов к объектам в вашем приложении.

Таким образом, это сопоставление URL-адресов с объектами, а не URL-адрес.

У вас есть 2 варианта:

использовать Router:: перенаправление

Что-то такое:

Router::redirect( '/videos/recent/*', '/videos/index/sort:published/direction:desc');

но похоже это не то, что вы хотите именно

использовать Router::connect

используйте обычный Router::connect, который подключит URL-адрес к некоторому действию, которое создаст соответствующую область. Что-то такое:

Router::connect(
    '/videos/recent/*',
    array(
        'controller' => 'videos', 
        'action' => 'recent'
     )
);

и в Видеоконтроллере

public function recent() {
    $this->request->named['sort'] = 'published';
    $this->request->named['direction'] = 'desc';
    $this->index();
}

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

что касается меня, мне нравятся обычные именованные параметры cakephp. Если такая область (опубликовано и описана) является вашим состоянием по умолчанию, просто закодируйте состояние по умолчанию в действии индекса. В более сложных случаях я считаю нормальным использовать обычные именованные параметры.

person Vadim    schedule 27.06.2013