Задача довольно тривиальная, а вот решение лично для меня на поверхности вообще не лежало…
Задача: у нас документы в разных контекстах лежат (не спрашивайте зачем). Так вот, нам надо организовать подмену УРЛов (то есть у нас своя маска УРЛов, и мы при обращении к сайту разбирая УРЛ точно знаем ID документа, который надо вывести), и нам надо вывести этот документ. Вопрос на засыпку: с какими трудностями мы можем столкнуться? Ответ: ни с какими!
В MODx есть функция — sendForward(); Но она очень замученная и далеко не для всего годится. В нашем же случае самый простой код выглядит вот так:
$modx->resource = $modx->getObject('modResource', $id);
$modx->request->prepareResponse();
exit();
Все. При чем пофиг на текущий контексты и т.п. Вешаете свой плагин на OnPageNotFound и рулите какие документы выводить. Никакого редиректа, просто вывод документа абсолютно в штатном режиме.
UPD: на одном проекте делали хитрый роутинг под клиента, и выяснилось, что данный метод не укладывается в заложенный механизм MODX-кеширования, а именно: в момент выполнения modRequest::handleRequest MODX берет найденный документ из кеша, включая обработанный контент, ТВ-параметры и т.п., и только потом отправляет на обработку modRequest::prepareResponse(). А если мы напрямую его вызываем с полученным документом, то у нас нет его кеша и каждый раз страница отрабатывается с нуля. Чтобы все корректно работало, надо делать типа такого:
if(!empty($modx->resource)){
return;
}
if($modx->resourceMethod == "alias"){
$request = preg_replace('/^\/+/', '', $_SERVER['REQUEST_URI']);
$q = $modx->newQuery('modResource');
$where = array(
"uri" => $request,
"deleted" => 0,
);
$q->where($where);
$q->select(array(
"id",
));
if($id = (int)$modx->getValue($q->prepare())){
$_REQUEST['id'] = $id;
unset($_REQUEST['q']);
$modx->handleRequest();
exit();
}
}
Конечно же у вас могут быть свои отличные методы поиска айдишника запрошенного документа, но самое главное это сброс $_REQUEST['q'], установка id нужного документа $_REQUEST['id'] и повторная обработка запроса $modx->handleRequest();
Вот так будет все работать с кешем.