отдельная страница сайта на MODx не из ресурсов

Добрый день. Есть подозрение что вы мало читаете топик вопросов. А скорее всего вы знаете ответ.
суть:
есть сайт на modx revo. есть своя компонента, в ней подключены свои таблицы.
Одна из них Kart где планируется хранить справочную информацию. она отличается по видам. Вид это отдельное поле.

как сделать что бы мой сайт мог отображать эту информацию по отдельной ссылке: МойСайт.ru/АлиасВида/АлиасКарточки
где АлиасВида это отдельное поле Alias в таблице KartVid, (линкуется 1 ко многим к таблице Kart по полю Vid)
АлиасКарточки — это отдельное поле Alias в таблице Kart

я пока вижу только один способ реализации: при создании новой карточки создавать в таблице где хранятся ресурсы новую запись
где в поле Alias прописывать значение АлиасВида/АлиасКарточки

но не хотелось бы перегружать модикс и хранить двойную информацию
подскажите как сделать что бы МОДИКС открывал такие ссылки без указания в ресурсах? где надо копать, или есть какие готовые решения плагины?
Legushka
08 декабря 2013, 15:00
modx.pro
1
1 865
0

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

Василий Наумкин
08 декабря 2013, 21:02
0
Для этого лучше использовать плагин на событие OnWebPageInit, проверять запрашиваемый url, и если он подходит по формату (например /special_section/alias1) — перехватывать управление на себя и генерировать страницу самостоятельно.

В общем, смотри файлы запрос и ответ — вся логика загрузки страниц MODX — там.
    Алексей Карташов
    08 декабря 2013, 21:59
    0
    Такой вариант (сперва распишу по пунктам, потом объясню логику):
    1. Создать настройку, назвать её, к примеру, «mycomponent.frontend_page» (где «mycomponent» — это название вашего компонента).
    2. Создать один ресурс, в котором планируется вывод данных из вашей таблицы или взять уже существующий.
    К примеру, возьмём главную страницу сайта (id главной = 1).
    3. Запишем в вышесозданную настройку цифру «1».

    И вот теперь надо написать плагин на событие «OnPageNotFound». Логика его такова:
    1. Разбираем урл. Примерно так:
    // получаем массив с частями урла
    $arr = parse_url($_SERVER['REQUEST_URI']);
    
    // Регулярка, которая выберет все названия "папкок" из урла.
    // К примеру урл имел вид http://www.site.ru/first1/second2/?sfgdg=tyu5466t35&qer=456#thisIsHash
    // В $arr['path'] лежит строка вида "/first1/second2/"
    // С помощью данной регулярки и функции preg_match_all мы получим массив, содержащий элементы:
    // "first1", "second2", "third3" (в том порядке, в котором они были в урле).
    //
    $mask = "/([^\/]+)/";
    preg_match_all($$mask, $arr['path'], $matches);
    
    $pathes = $matches[0];
    
    // Проверяем количество, чтобы отсечь заведомо другие урлы, в которых папок больше, чем нам нужно
    // (а нужно нам "АлиасВида/АлиасКарточки")
    // Не ноль и меньше 2х
    if (count($pathes) && count($pathes) <= 2) {
    	$i = 0;
    	$good = false;
    	foreach ($pathes as $path) {
    		/**
    		 * и вот здесь логика такая:
    		 * на нулевом шаге ищем нужным нам "алиас вида" в собственной таблице (не забываем свой пакет через $modx->addPackage()).
    		 * 
    		 */
    		switch ($i) {
    			case 0:
    				// здесь пишем название своего класса
    				$vid = $modx->getObject('Vid', array(
    					'alias' => $path
    				));
    				if ($vid instanceof 'Vid') {
    					$good = true;
    					$aliasVid = $path;
    					// устанавливаем глобальный плейсхолдер, который будет доступен в шаблоне как [[+aliasVid]],
    					// который можно будет использовать как угодно (например, подставить в условие сниппета pdoTools)
    					$modx->setPlaceholder('aliasVid', $aliasVid);
    				} else {
    					break 2; // выходим из switch И ИЗ ЦИКЛА foreach (http://www.php.net/break)
    				}
    				break 1; // выходим из switch
    				
    			case 1:
    				// здесь всё по аналогии, за исключением $good
    				$kart = $modx->getObject('Kart', array(
    					'alias' => $path
    				));
    				if ($kart instanceof 'Kart') {
    					$aliasKart = $path;
    					$modx->setPlaceholder('aliasKart', $aliasKart);
    				}
    				break;
    		}
    		
    		$i++;
    	}
    	if ($good) {
    		// если есть совпадения алиасов, то грузим документ, который записан в настройке
    		$docId = $modx->getOption('mycomponent.frontend_page');
    		if (!$docId) return;
    		$modx->resource = $modx->getObject('modResource', $docId);
    		$modx->request->prepareResponse();
    		exit;
    	}
    }
    Код не проверялся вообще!
    Используйте его как пример логики (которая, кстати, тоже может быть не верной :-)).

    Удачи!
      Legushka
      09 декабря 2013, 21:08
      0
      вот пойми вас светлых голов) от простых вопросов у вас стоит фреймворк а от сложных все расписали)
      реально спасибо большое!
        Алексей Карташов
        11 декабря 2013, 22:19
        0
        Вы хоть отпишитесь — помогло или нет. Интересно же =)
          Legushka
          15 декабря 2013, 00:09
          0
          Алексей я пока еще не смог реализовать так как не разу еще не писал плагины на события. Временно для ссылок сделал реальные ресурсы, в которых вывожу инфу из своих таблиц. Просто в ресурсе одно поле задействовал для хранения ИД карточки, и по нему уже получаю данные. в шаблоне идет вывод на экран этой карточки

          но это решение для моего случая неверное и теперь сложилась одна ситуация когда всетаки надо научится парсить ссылку и получать нужные данные в зависимости от этой ссылки
            Legushka
            15 декабря 2013, 01:04
            0
            начало положено, нашел где это делается, добился первого «привет мир»
            <?php
            switch($modx->event->name) {
                case 'OnPageNotFound':    
                    // если URI пуст, отправляем на стартовую страницу контекста
                    $modx->sendForward('56');
                break;
            }
            сделал такой простенький редирект вместо 404 на конкретную страницу и это заработало, теперь буду учится парсить свою страницу)
            Legushka
            15 декабря 2013, 01:38
            0
            $$mask… вы явно на что-то намекали)
              Legushka
              15 декабря 2013, 01:52
              0
              Алексей. Однозначно помогло) подскажите еще как можно передать пару переменных из плагина в вызываемый ресурс?
              собираюсь сделать так: универсальный ресурс для вывода видов карточек с журналом карточек
              и универсальный ресурс для вывода текущей карточки

              в них надо будет передать пару значений из плагина после распарсивания урла: ИД вида карточки и для второго случая ИД вида карточки и ИД карточки

              спасибо большущее за стартовый пример!
                Legushka
                15 декабря 2013, 11:41
                0
                Алексей, я еще раз переосмыслил зачем нужна была настройка mycomponent.frontend_page. Если я правильно понял то как рас ее и используют для передачи переменной в загружаемый ресурс? пара вопросов про эту настройку: она персональная для каждой сессии: пользователь-закладка-браузера
                или она общая?
                если я в настройку буду сохранять свои значения, они не повлияют на вывод у других посетителей или у этого же но на другой закладке браузера?
                или есть проще путь передачи переменной из плагина в ресурс/чанк/снипет/шаблон? подскажите плиз.
                  Legushka
                  15 декабря 2013, 13:45
                  0
                  работают плейсхолдеры)
                    Legushka
                    16 декабря 2013, 13:52
                    0
                    работает) не забыдь убрать галочку кешировать с универсального ресурса) а то распарсенная ссылка по прошлому откроется)
          Legushka
          26 декабря 2013, 09:19
          0
          все работает) спасибо большое
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            12