Периодически появляется задача — создать несколько контекстов и сделать так, чтобы нужный загружался для работы автоматически в зависимости от URL. Будем считать, что ЧПУ настроены. Более никаких изменений ни в .htaccess, ни в конфигах сервера. Ведь часто встречаются злые хостеры, которые не позволяют этого делать. А еще нежелательно создавать подкаталоги и копировать в них index.php, иначе после каждого обновления придется следить за его изменением.

Мы будем переключать контексты с помощью плагина на событие OnHandleRequest.
Есть 2 основных вида URL, которые надо обрабатывать:
  • context.site.ru
  • site.ru/context/
Поскольку между этими вариантами отличаются только плагин и три настройки контекстов, предварительно опишем общие действия:
  • Создать субдомен его направить на тот же каталог, где лежит основной сайт ИЛИ создать алиас для основного домена;
  • Создать контекст и следующие его настройки:
    • error_page = ID страницы для 404 ошибки в данном контексте
    • site_name = Название сайта для этого контекста

    • site_start = ID главной страницы в данном контексте
  • Создаем плагин с любым именем (например, swCtx), отмечаем галкой событие onHandleRequest.

Первый вариант очень простой, плагин имеет всего несколько строк.
Для соответствующего контекста создаем следующие настройки:
В нашем плагине пишем следующий код:
<?php
if ($modx->event->name == 'OnHandleRequest') {
    if ($modx->context->get('key') == 'mgr') {return;}
    // сравнение текущего имени хоста и искомого
    if (strstr($_SERVER['HTTP_HOST'], 'testen.a.aaa0.ru') != false) {
        $modx->switchContext('endomain');
        return;
    }
}


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

if (strstr($_SERVER['HTTP_HOST'], 'context.site.ru') != false) {
        $modx->switchContext('context');
        return;
    }

, заменив в нем название контекста и субдомена.
Больше ничего.

Со вторым вариантом чуть сложнее. Дело в том, что uri страницы записывается относительно контекста. Соответственно, из стандартной переменной запроса $_REQUEST['q'] нужно вырезать часть пути, относящуюся к контексту.

Настройки контекста:
В коде плагина комментарии позволяют понять всю его логику, дополнительно описывать не будем.

<?php
if ($modx->context->key == 'mgr') {return;}

elseif ($modx->event->name == 'OnHandleRequest') {
	 // Получаем названием переменной запроса, затем ее значение
	$var = $modx->getOption('request_param_alias', null, 'q');
	$request = $_REQUEST[$var];
	
	 // Проверяем, стоит ли в начале запроса путь контекста 
	if (strpos($request, 'context/') === 0) {
		$modx->switchContext('context');
		// Вырезаем лишнее 
		$_REQUEST[$var] = substr($request, 8);
	}
}


Переключив контекст и изменив запрос, более не вмешиваемся в работу движка. Дальше все будет обработано стандартным образом.

P.S.: Спасибо Василию за изначальную идею и правильный плагин для второго варианта.