Работа с поддоменами в MODx

в 0:06, , рубрики: modx, modx revolution, поддомены, метки: ,

Тут от товарища поступил вопрос:

День добрый!

Читаю статью про дружбу ModX и LS, и решил спросить вопрос, который сам никак в ModX не могу решить — как реализовать логику работы Revo в зависимости от текущего поддомена основного сайта?

Я вижу на pro-cent.ru, что в поддомен выносится название города (http://kaliningrad.pro-cent.ru/). ModX как-то помогает в обработке этого, или у Вас все руками и своим кодом сделано?

Решил дать ответ в публику, наверняка кому-нибудь тоже пригодится.

Вообще на хабре писали уже, что для работы с несколькими доменами (точнее переключениями между ними), необходимо использовать метод $modx->switchContext($ctx); Это безусловно очень полезная штука, но в нашем случае она нас не спасает, так как в случае переключения в другой контекст, у нас пропадает возможность просто так обратиться к документам нашего базового контекста (в данном случае web), а так же с настройками контекстов тонкости есть. В общем $modx->switchContext() нужен тогда, когда целевой контекст полностью самостоятельный, имеет свои документы и т.п.

В моем же случае у меня есть базовый контекст и в нем уже есть все нужные мне документы, а контексты по городам а-ля krasnodar нужны только для того, чтобы перегрузить некоторые настройки (каждый контекст имеем свои настройки типа базовый домен, город, код Я.Метрики и т.п.), в общем все то, чтобы легко определить какие акции выводить и т.п.

Так вот, всем советую больше внимания уделять плагинам. Им не так много посвещают тем, но именно плагины позволяют как угодно вклиниваться в логику работы MODx, при этом совершенно не трогая кода самого движка.

В общем, для того, чтобы решить нашу задачу, делаем следующее:

1. Создаем нужные нам контексты и прописываем в них нужные настройки.

2. Создаем плагин и указываем выполнение по событию OnHandleRequest

3. В плагин пишем следующее (или типа того) (Не оформляю в , потому что переносы бьются).

<?php

// Здесь можно разделить логику в зависимости от контекста
switch($modx->context->key){
case 'web':
break;
default: return;
}

// Пытаемся определить домен 3-го уровня и определить, является ли это контекстом
if(preg_match('/([^.]+).[^.]+.[^.]+$/',$_SERVER['HTTP_HOST'], $match)){
if($ctx = $modx->getObject('modContext', $match[1])){
// Выполняем инициализацию контекста
if($ctx->prepare()) {
// Перегружаем настройки MODx-а
// Только следует учитывать, что такие измененные настройки возможно получить только через API $modx->getOption();
// Шаблонизатор не перегрузить, то есть если в чанке у вас написано [[++site_name]], подобные хак на него не повлияет
// будьте внимательны
$modx->config = array_merge($modx->config, $ctx->config);
}
}
}

// Из настроек определяем главный хост
// Кому-то он не обязательнен, но у меня в случае несоответствия хоста происходит редирект,
// чтобы какой-нибудь глупый поисковый робот
// не наплодил поддоменнов
if(!$host && (!$host = $modx->config['mainHost'])) {
// print "Не указан основной хост для контекста ".$modx->context->key;
return;
}

// print $host;
$redir_host = '';
$redir_url = '';

// Здесь можно раскидать логику при выполнении различных событий
switch($modx->event->name){
case 'OnPageNotFound':

break;
case 'OnHandleRequest':

break;

default: ;
}

// Проверяем на соответствие основному хосту
if(!preg_match('/^'.$host.'$/i', $_SERVER['HTTP_HOST'])){
$redir_host = $host;
$redir_url = $_SERVER['REQUEST_URI'];
}

// Если основной хост из настроек не соответствует, то делаем 301-ый редирект (редирект каждый напишет)
if($redir_host || $redir_url){
$params = array();
$redir_url ? $params['url'] = $redir_url : "";
$redir_host ? $params['hostl'] = $redir_host : "";
$modx->runSnippet('redirect', $params);
}

Собственно все.

Автор: Fi1osof


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js