MODX

Простая маршрутизация для MODX Revolution

MODX Fast Router

В этом компоненте используется вот эта замечательная библиотека github.com/nikic/FastRoute.

Компонент предназначен для построение простой и легкой маршрутизации в приложении на базе MODX Revolution.

Например вы решили хранить "новости/статьи/что-то другое" в отдельной таблице, чтобы не засорять дерево в админке большим кол-вом ресурсов.

Для этого создадим новый маршрут в чанке fastrouter.

[
    ["GET","/news/{alias:[a-zA-Z0-9-]+}.html","1"]
]

где {alias:[a-zA-Z0-9-]+} это алиас новости, например my-super-news, [a-zA-Z0-9-]+ регулярное выражение пропускающее только символы от a до Z - в адресе, 1 - ID ресурса (так называемый контроллер, который будет обрабатывать текущий маршрут) со сниппетом который реализует вашу логику показа новости. Так же в качестве обработчика (третьего параметра в маршруте) можно указать имя сниппета.

Например, простой сниппет, получает новость по alias из базы и создает плейсхолдеры всех свойств с префиксом news.:

<?php

$key = $modx->getOption('fastrouter.paramsKey', null, 'fastrouter');
$params = isset($_REQUEST[$key]) ? $_REQUEST[$key] : array();
$alias = isset($params['alias']) ? $params['alias'] : null;

if ($alias) {
    $news = $modx->getObject('modNews', array('alias' => $alias));

    if ($news) {
        return $modx->setPlaceholders($news->toArray(), 'news.');
    }
}

return '';

Объявлять маршруты нужно в чанке fastrouter в таком формате:

[
    ["GET","/fastrouter/{name}/{id:[0-9]+}","1"],
    ["GET","/fastrouter/{id:[0-9]+}","1"],
    ["GET","/hello/{name:\\D+}","1"],
    ["GET","/some_snippet/{id}","fastrouter"],
    ["GET","/contact","1"]
]
  • Первый параметр GET метод запроса, может быть GET, POST.
  • Второй параметр /fastrouter/{name}/{id:[0-9]+} наш маршрут, где {name} именованный параметр принимающий любые символы, {id:[0-9]+} именованный параметр принимающий только цифры. Можно использовать любые валидные регулярные выражения.
  • Третий параметр 2 ID ресурса куда будет направлен запрос.

Если запрошенному URL не соответствует ни один объявленный маршрут, будет сгенерирована 404 ошибка.

Если использовать в качестве обработчика ID ресурса, то все именованные параметры попадут в массив fastrouter в глобальном массиве $_REQUEST. В нашем случае по первому маршруту, например http://site.com/fastrouter/vanchelo/10 получим вот такие данные:

var_dump($_REQUEST);
Array
(
    [fastrouter] => Array
        (
            [name] => vanchelo
            [id] => 10
        )
)

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

$key = $modx->getOption('fastrouter.paramsKey', null, 'fastrouter');
$params = $modx->getOption($key, $scriptProperties, array());

return '<pre>' . print_r($params, true) . '</pre>';

По умолчанию имя ключа со всеми параметрами маршрута - fastrouter. Для задания своего ключа измените в настройках системы параметр fastrouter.paramsKey.

Скачать готовый пакет здесь github.com/vanchelo/modxFastRouter/releases/download/1.0.2-pl/fastrouter-1.0.2-pl.transport.zip

16 Комментариев

alt.point # 2015-04-03 18:09:06
Приветствую, Иван. Если не секрет, с чем связано решение хранить настройки в чанке? Почему не хранить тот же JSON массив в таблице и не выводить в компоненте гридом? Или суть разработки была в том, что бы сделать быстро и лёгкое решение? В действительности для специалистов всё равно где вносить правки, в файле, чанке или же пользоваться интерфейсом админки, но может есть какой-то «тайный секретныйсекрет» по которому было принято такое решение?
Брежнев Иван Автор # (комментарий был изменён) 2015-04-03 18:30:44
Решение было принято в концепции MODX. Изначально роуты все прописывались в файле routes.php, но я решил что пользователю будет не удобно добавлять новые маршруты таким образом, а более опытные разработчики могут сделать как им удобно.

Планов сделать грид с роутами не было
alt.point # 2015-04-03 18:36:00
Спасибо за ответ
Брежнев Иван Автор # 2015-04-04 03:32:50
Если есть необходимость могу сделать опцию для возможности выбора между хранением роутов в чанке или в файле.
alt.point # 2015-04-04 14:25:16
Да я и сам могу, оно не принципиально же где оно хранится. Мне было интересно, может есть какая-то «тайная тайна», что ты решил хранить в чанке, потому и спросил, вдруг я чего не знаю =)
russel gal # 2015-04-16 05:50:13
Было бы здорово добавить опцию обработки роута сниппетом, для AJAX-запросов, например.
Брежнев Иван Автор # 2015-04-16 05:56:30
Т.е. вместо ID ресурса чтобы можно было указывать имя сниппета?
russel gal # 2015-04-16 06:11:20
Да, получится еще один способ обработки AJAX-запросов :)
Элегантно. Я так думаю.
Брежнев Иван Автор # 2015-04-16 06:16:36
А ответ из сниппета каким образом возвращать?
alt.point # 2015-04-16 06:24:08
Через JSONP например ответ может быть, раз уж это AJAX
Брежнев Иван Автор # (комментарий был изменён) 2015-04-16 16:11:12
Ага, это уже детали, я спрашивал о том что russel gal ниже написал
russel gal # 2015-04-16 08:21:11
Пусть сниппет сам решает как отдавать :)
Типа этого:
protected function handle($id, array $data)
    {
        $_REQUEST += array($this->paramsKey => $data);

        if (is_numeric($id)) {
            $this->modx->sendForward($id);
        } else {
            echo $this->modx->runSnippet($id);
            die;
        }
        return null;
    }
Брежнев Иван Автор # 2015-04-16 16:09:00
Так можно сделать =)
Брежнев Иван Автор # 2015-04-16 16:09:43
Вы кстати можете прислать мне pull request на github
russel gal # 2015-04-16 21:28:31
Я не силен особо, но отправил.
Теперь можно задать роуты, например, так:
[
    ["GET","/catalog/{alias:[a-zA-Z0-9-.]+}.html","9"],
	["POST","/catalog/{alias:[a-zA-Z0-9-.]+}.html","fastrouter"]
]

ГЕТом будет отдаваться ресурс 9, ПОСТом сниппет fastrouter
Брежнев Иван Автор # (комментарий был изменён) 2015-04-19 20:44:39
Выпустил новый релиз github.com/vanchelo/modxFastRouter/releases/tag/1.0.2-pl
Чтобы оставить комментарий необходимо авторизоваться