К содержанию

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

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

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

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

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

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

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

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

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

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

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

      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, 12:24
        Максим Кузнецов
        Максим Кузнецов Проверенный
        28 января 2015, 13:03
        Спасибо.)

        Подскажите, пожалуйста, какие-то дополнительные настройки контекстов для вашего плагина нужно реализовывать и получится ли на нем реализовать задачу без создания «папки-контейнера»?
          Илья Уткин
          Илья Уткин Администратор
          28 января 2015, 13:05
          Ничего не нужно кроме самого плагина.
            Максим Кузнецов
            Максим Кузнецов Проверенный
            28 января 2015, 13:51
            ох… *плача* спасибо… спасибо %))
          Илья Уткин
          Илья Уткин Администратор
          28 января 2015, 13:53
          Для истории, вот код плагина:
          <?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
            Единственная специфика, если вызывается линк, не существующий в структуре, то отдается не 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
              Вместо редиректа можно сделать просто
              return '';
              тогда 404 ошибкой займется сам MODX
            Василий
            Василий Старожил
            13 апреля 2015, 13:17
            Подскажите пожалуйста как быть если одинаковые uri есть в разных контекстах? Как сделать так, чтобы сначала проверялась принадлежность uri к текущему контексту, а вот если в текущем нет, тогда бы искалось в других и по результатам переключался конекст.
              Сергей Шлоков
              Сергей Шлоков Эксперт
              13 апреля 2015, 13:39
              Как сделать так, чтобы сначала проверялась принадлежность uri к текущему контексту
              Так и делается по умолчанию. Если в текущем контексте нет, то возникает ошибка 404. Значит надо ловить событие onPageNotFound и искать в другом контексте. Отсюда возникает вопрос — если одинаковых uri несколько, какой брать? И второй вопрос — обязательно ли переключать контексты? Может вполне достаточно форвардить запрос, оставляя пользователя в текущем контексте?
                Василий
                Василий Старожил
                13 апреля 2015, 15:15
                Да, я не досмотрел, действительно это делается по умолчанию, но проверка осуществляется в самом конце. Я имел ввиду поменять немножко логику работы. Т.е. сначала идет поиск uri в текущем контексте, и только если он там не найдет идет поиск в других.
                  Илья Уткин
                  Илья Уткин Администратор
                  13 апреля 2015, 16:22
                  Если в текущем контексте uri существует, плагин просто-напросто не будет запущен. Поэтому никакой проверки нет — если код начал выполнятся, значит uri в текущем контексте точно нет.
                    Илья Уткин
                    Илья Уткин Администратор
                    13 апреля 2015, 16:24
                    А, нет, ошибся. Для вас этот плагин просто нужно запускать по событию onPageNotFound, а не onHandleRequest
                      Василий
                      Василий Старожил
                      13 апреля 2015, 16:30
                      onPageNotFound не хочется трогать…
                        Воеводский Михаил
                        Воеводский Михаил Проверенный
                        13 апреля 2015, 16:43
                        А зря. Отдайте проверку на существование в текущем контексте MODX'у. Зачем это делать самостоятельно?

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

                                Как догадаться, что поможет, если ты не выкладываешь код плагина?
                                Василий
                                Василий Старожил
                                13 апреля 2015, 19:57
                                Так код-то практически и не менял.
                                <?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
                                После смены контекста необходимо отправить пользователя на найденную страницу через $modx->sendForward();
                                Василий
                                Василий Старожил
                                13 апреля 2015, 21:22
                                Спасибо, это решило проблему!
                Николаевич
                Николаевич Старожил
                07 марта 2017, 13:29
                У вас нормально отрабатываются GET-запросы в контекстах, отличных от основного?
                У меня site.ru работает, а site.ru?theme=mobile отдает 404
                  Николаевич
                  Николаевич Старожил
                  07 марта 2017, 14:46
                  $resource = $modx->getObject('modResource', array('uri' => $uri));
                  заменил на
                  $uri = explode('?', $uri, 2);
                  $resource = $modx->getObject('modResource', array('uri' => $uri[0]));
                  и заработало
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              27