Контексты для разделения страниц

Здравствуйте.

Возникла следующая проблема — при создании разных контектов для визуального и правового разделения ресурсов, имеющих один корень (для примера: основной контекст «web» и дополнительный «cars», все документы которых доступны по адресу site.ru/название_страницы).
Реализация путем контекстов выбрана для того, чтобы в одном табе не были в перемешку системные страницы и 100-150 марок автомобилей.

Все страницы не основного контекста определяются как «несуществующие» и перебрасывают на ошибку 404.

Подскажите, пожалуйста, как можно реализовать контексты для подобной задачи или задачи для контекстов, находящихся в рамках одного домена, но отличающихся родительским «контейнером» (пример: site.ru/название_страницы и site.ru/folder/название_страницы).

Заранее спасибо.

P.s. да, я знаю, что контексты — это гемморой и далеко не всегда оправданное решение.
Максим Кузнецов
27 января 2015, 17:32
modx.pro
5
5 159
0

Комментарии: 27

Максим Кузнецов
27 января 2015, 20:35
0
UPD: параметр allow_forward_across_contexts не помог, т.к. даже при «просмотре» ресурса через админку вываливается 404 ошибка.

Настройки доп. контекста:

base_url: /
http_host: site_name.ru
site_start: 1
site_url: site_name.ru/
      Максим Кузнецов
      28 января 2015, 10:57
      0
      Спасибо, это уже читал. Тут вопрос, скорее, в том, чтобы реализовать контекст без создания в нем «дефолтной страницы».

      UPD: реализовал предложенным методом, все отлично, кроме одного нюанса:

      Структура контекста (brends):
      — Список брендов (псевдоним brends, id — 368)
      — — бренд 1
      — — 2
      — — x

      Настройки контекста (brends):
      base_url: /brends/
      site_url: адрес_сайта/brends/
      site_start: 368

      При заходе на внутренние страницы бренда (1, 2, 3) — все корректно работает, правда появляется ненужный фолдер в пути /brends/brends/название (именно из-за этого спрашивал по поводу реализации контекста без site_start).

      Но, если я захожу по адресу /brends/brends/, то правилами .htaccess адрес становится вида /brends (откусывается "/" и, видимо, пропадает псевдоним главной страницы, в результате отдавая 404 ошибку).

      .htaccess:
      AddDefaultCharset utf-8
      Options +FollowSymLinks
      RewriteEngine On
      RewriteBase /
      
      
      #убираю дубль index.php
      RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
      RewriteRule ^index\.php$ /$1 [R=301,L]
      
      
      #склейка www
      RewriteCond %{HTTP_HOST} .
      RewriteCond %{HTTP_HOST} ^www.(.*)$ [NC]
      RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
      
      
      #откусываю слэш
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.+)/$ /$1 [R=301,L]
      
      
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

      Подскажите, пожалуйста, как можно избавиться от этого эффекта?
        Максим Кузнецов
        28 января 2015, 13:03
        0
        Спасибо.)

        Подскажите, пожалуйста, какие-то дополнительные настройки контекстов для вашего плагина нужно реализовывать и получится ли на нем реализовать задачу без создания «папки-контейнера»?
        Илья Уткин
        28 января 2015, 13:53
        1
        0
        Для истории, вот код плагина:
        <?php
        if ($modx->event->name != "OnHandleRequest"
            || $modx->context->key == 'mgr') {
               return;
            }
        
        if ($_SERVER['REQUEST_URI'] != '/') {
            $uri = substr($_SERVER['REQUEST_URI'],1);
            if (substr($uri,-5) != '.html' && substr($uri,-1) != '/') {
              $uri .= '/';
            }
            $resource = $modx->getObject('modResource', array('uri' => $uri));
            $ctx = $resource->get('context_key');
        } else {
            $ctx = 'web';
        }
        
        if ($ctx != $modx->context->key){
              $modx->switchContext($ctx);
        }
          Максим Кузнецов
          28 января 2015, 18:53
          0
          Единственная специфика, если вызывается линк, не существующий в структуре, то отдается не 404-ошибка, а — Fatal error: Call to a member function get() on a non-object

          Заменил строку:
          $ctx = $resource->get('context_key');
          На:
          if (!empty($resource)) {
          		$ctx = $resource->get('context_key');
          	}
          	else{
          		//тут редирект на мою 404 страницу.
          	}
            Илья Уткин
            28 января 2015, 19:03
            0
            Вместо редиректа можно сделать просто
            return '';
            тогда 404 ошибкой займется сам MODX
          Василий
          13 апреля 2015, 13:17
          0
          Подскажите пожалуйста как быть если одинаковые uri есть в разных контекстах? Как сделать так, чтобы сначала проверялась принадлежность uri к текущему контексту, а вот если в текущем нет, тогда бы искалось в других и по результатам переключался конекст.
            Сергей Шлоков
            13 апреля 2015, 13:39
            0
            Как сделать так, чтобы сначала проверялась принадлежность uri к текущему контексту
            Так и делается по умолчанию. Если в текущем контексте нет, то возникает ошибка 404. Значит надо ловить событие onPageNotFound и искать в другом контексте. Отсюда возникает вопрос — если одинаковых uri несколько, какой брать? И второй вопрос — обязательно ли переключать контексты? Может вполне достаточно форвардить запрос, оставляя пользователя в текущем контексте?
              Василий
              13 апреля 2015, 15:15
              0
              Да, я не досмотрел, действительно это делается по умолчанию, но проверка осуществляется в самом конце. Я имел ввиду поменять немножко логику работы. Т.е. сначала идет поиск uri в текущем контексте, и только если он там не найдет идет поиск в других.
                Илья Уткин
                13 апреля 2015, 16:22
                0
                Если в текущем контексте uri существует, плагин просто-напросто не будет запущен. Поэтому никакой проверки нет — если код начал выполнятся, значит uri в текущем контексте точно нет.
                  Илья Уткин
                  13 апреля 2015, 16:24
                  0
                  А, нет, ошибся. Для вас этот плагин просто нужно запускать по событию onPageNotFound, а не onHandleRequest
                    Василий
                    13 апреля 2015, 16:30
                    0
                    onPageNotFound не хочется трогать…
                      Воеводский Михаил
                      13 апреля 2015, 16:43
                      0
                      А зря. Отдайте проверку на существование в текущем контексте MODX'у. Зачем это делать самостоятельно?

                      MODX проверит существование и, если не найдет, запустит плагин, где уже будет поиск во всех контекстах.
                        Василий
                        13 апреля 2015, 16:54
                        0
                        Переназначил плагин на событие onPageNotFound, итог — 503 Error
                        Page not found
                        The page you requested was not found.
                          Воеводский Михаил
                          13 апреля 2015, 17:55
                          0
                          Надо смотреть на код плагина.
                            Володя
                            13 апреля 2015, 18:22
                            0
                            задать error_page для контекста?
                              Воеводский Михаил
                              13 апреля 2015, 18:36
                              0
                              Ты предлагаешь заниматься гаданием на кофейной гуще. Или ищешь телепатов, которых здесь нет.

                              Как догадаться, что поможет, если ты не выкладываешь код плагина?
                              Василий
                              13 апреля 2015, 19:57
                              0
                              Так код-то практически и не менял.
                              <?php
                              
                              if ($modx->event->name != "onPageNotFound"
                                  || $modx->context->key == 'mgr') {
                                     return;
                                  }
                              
                              if ($_SERVER['REQUEST_URI'] != '/') {
                                  $uri = substr($_SERVER['REQUEST_URI'],1);
                                  if (substr($uri,-5) != '.html' && substr($uri,-1) != '/') {
                                    $uri .= '/';
                                  }
                                  $resource = $modx->getObject('modResource', array('uri' => $uri));
                                  if (!empty($resource)) {
                              	    	$ctx = $resource->get('context_key');
                              	    }
                              	    else{
                              		    return '';
                                  	}
                              } else {
                                  $ctx = 'web';
                              }
                              
                              if ($ctx != $modx->context->key){
                              	    $modx->switchContext($ctx);
                                  }
                              Воеводский Михаил
                              13 апреля 2015, 20:04
                              0
                              После смены контекста необходимо отправить пользователя на найденную страницу через $modx->sendForward();
                              Василий
                              13 апреля 2015, 21:22
                              0
                              Спасибо, это решило проблему!
              Николаевич
              07 марта 2017, 13:29
              0
              У вас нормально отрабатываются GET-запросы в контекстах, отличных от основного?
              У меня site.ru работает, а site.ru?theme=mobile отдает 404
                Николаевич
                07 марта 2017, 14:46
                0
                $resource = $modx->getObject('modResource', array('uri' => $uri));
                заменил на
                $uri = explode('?', $uri, 2);
                $resource = $modx->getObject('modResource', array('uri' => $uri[0]));
                и заработало
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            27