We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 17459
    • 268 Posts
    Приветствую, коллеги!

    описание: есть категории товара, в них вложенные странички товаров, на страничке категории товара есть неизвестное заранее число картинок (у категории может быть один из четырёх шаблонов на выбор менеджера сайта отличающихся количеством и размерами картинок), после выбора шаблона категории подгружаются поля с картинками и ссылками, куда эти картинки должны вести (то есть менеджер сопоставляет картинки категории тем товарам, которые внутри категории, выбирая их из раскрывающихся списков рядом с каждой картинкой..

    задача сделать в TV шаблона категории раскрывающийся список ресурсов внутри текущего ресурса, для этого надо сначала получить ид текущего ресурса, и потом getDocumentChildren его...

    Подскажите, почему
    <?php
    $output = $modx->documentIdentifier; return $output;
    ?>

    работает в сниппете, но не работает в TV (@EVAL $output = $modx->documentIdentifier; return $output; )


    на всякий случай пробовал добавить global $modx; (не очень правда понимая зачем),
    также пробовал $modx->documentObject[’id’]

    Evo 1.0.3

    другие $modx-> в TV работают (получает, например, список поддокументов для ресурса с ид=-1 с помощью $modx->getDocumentChildren)

    P.S. Я понимаю, что для нового ресурса ид не будет показываться корректно, потому что ещё никакого ид нет, ресурс не сохранен. Этот ТВ будет заполняться уже после сохранения категории (вообще говоря, категории будут созданы сначала, а потом только будут меняться (а именно, картинки и, разумеется, ссылки))

    Ещё раз вопрос:
    Как мне узнать в TV свой ид в случае если он есть (ресурс был сохранён)?
      • 785
      • 2,113 Posts
      Не совсем понятно, что и где надо получить. Значение $modx->documentIdentifier доступно при генерации страницы, а при работе в административной части его нет. Если надо что-то делать при редактировании страницы в административной части, следует писать плагины, и в зависимости от того, к какому событию они будут привязаны, им будут передаваться определенные данные.
        Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
        Статьи о MODx, регулярно новые публикации
        • 17459
        • 268 Posts
        Ок, упрощу.

        Допустим, у меня есть ресурс, с именем "Цветы". В него вложены три ресурса "Роза", "Ландыш" и "Тюльман".
        К шаблону для документа "Цветы" привязано два TV. Одно из них categoryImage (картинка), второе categoryLink (раскрывающийся список). В поле categoryImage менеджер сайта будет загружать картинку, а в поле categoryLink должен выбрать одно из трёх значений: Роза, Ландыш или Тюльман. Эти значения должны генерироваться на лету (содержать актуальные данные на основе выборки по под-ресурсам редактируемого ресурса). Если он выберет Ландыш, то ссылка с картинки будет на ресурс Ландыш. Процесс должен быть именно таким (то есть ссылку на картинку выбирают именно со страницы категории, выбирая из вложенных ресурсов)


        Поле categoryLink я пытался сделать так:
        @EVAL $myid = $modx->documentIdentifier; $children = $modx->getDocumentChildren($myid); foreach($children as $child) {$output .= $child['pagetitle']."==".$child['id']."||"; } return $output;


        В результате $myid пустая и getDocumentChildren выдаёт список из корневых ресурсов, а не из тех, что вложены в мой ресурс.


        Подскажите, как написать плагин и какие поставить события на него чтобы решить эту задачу? Или как вообще мне это сделать? То есть TV должен знать ID ресурса, который я сейчас редактирую чтобы сформировать список вложенных в него ресурсов.

        То есть если ресурс "Цветы" имеет id 123, то в TV categoryLink на этом ресурсе должен выполниться код

        @EVAL $children = $modx->getDocumentChildren(123); foreach($children as $child) {$output .= $child['pagetitle']."==".$child['id']."||"; } return $output;


        То есть не обязательно заставить работать именно $myid = $modx->documentIdentifier; Главное - как угодно вставить туда 123 перед тем как выполнится @EVAL
          • 1788
          • 1,103 Posts
          @EVAL function getItems($p, $l=0){ global $modx; $c=$modx->getDocumentChildren($p,1,0,"*",’’,"pagetitle","ASC",""); foreach($c as $k) {$out.=str_pad("",$l*2,".",STR_PAD_RIGHT)." ".$k[’pagetitle’]."==".$k[’id’]."||"; $out.=getItems($k[’id’],$l+1);} return $out;} return getItems(id_родителя);
            • 17459
            • 268 Posts
            Всё верно, мой код выше делает точно то же самое... Проблема в том, что я не знаю как получить из TV id_родителя. Потому что id_родителя = id редактируемого в данный момент документа.


            Может быть, кстати не через @EVAL а на jQuery подставить значения... Только их всё равно надо получить в плагине может... только как?

            В TV должен быть список ресурсов, вложенных в редактируемый в данный момент ресурс (если они есть, конечно - их может не быть в случае если а) их и правда нет б) редактируемый ресурс ещё ни разу не сохранялся и у него ещё нет id)
              • 785
              • 2,113 Posts
              Плагин на событие OnDocFormRender позволяет узнать все, что надо (global $id), а также исправить сформированные поля до их вывода. И не надо ни @EVAL ни jQuery.
                Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
                Статьи о MODx, регулярно новые публикации
                • 17459
                • 268 Posts
                посмотрел Inherit Parent Template, попробовал сделать по аналогии

                global $content;
                global $id;
                $e = &$modx->Event;
                
                switch($e->name) {
                    case 'OnDocFormRender':
                        if(($_REQUEST['pid'] > 0) && ($id != 0) && ($content['isfolder'] == 1)): // если ресурс существует и папка
                            if($content['template'] == 11 || $content['template'] == 17 || $content['template'] == 18 || $content['template'] == 19): // проверяем, является ли документ категорией
                                // дальше мы генерируем значение для поля, в упрощенном виде как-то так (или как написал antey выше):
                                $children = $modx->getDocumentChildren($id); 
                                foreach($children as $child) {
                                    $output .= $child['pagetitle']."==".$child['id']."||"; 
                                }
                                $content['categoryLink'] = $output; // тут мы присваиваем значение TV categoryLink, чувствую, что тут ошибка
                            endif;
                        endif;
                    break;
                
                    default:
                        return;
                        break;
                }
                



                Поправьте, плз, где я ошибся?.. Не могу найти документацию по событиям/плагинам.. Не понимаю, почему именно $content

                http://svn.modxcms.com/docs/display/Evo1/Plugins
                вот тут оч мало..
                  • 785
                  • 2,113 Posts
                  Посмотрел – с TV не получится, как я думал сначала, для них нет отдельных переменных. Да и $content при событии OnDocFormRender поздно менять – страница уже сформирована. Для решения проблемы лучше всего записывать список в таблицу site_tmplvars при каждом сохранении документа, то есть во время события OnDocFormSave. Надо проверять, не требуется ли обновить какой-то из списков, и если надо, записывать его в таблицу. А при следующем редактировании родительского документа список уже будет верным.
                    Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
                    Статьи о MODx, регулярно новые публикации
                    • 17459
                    • 268 Posts
                    Мне кажется не очень удобным такой подход.

                    Тогда лучше не при сохранении, а при загрузке (..PreRender) обновлять TV с помощью http://svn.modxcms.com/docs/display/Evo1/query данные по TV

                    Какие события я могу использовать чтобы они выполнились раньше, чем @EVAL в TV? То есть я бы мог просто подставить туда нужную айдишку.. А потом бы выполнился @EVAL.. Так можно?

                    Где-то можно почитать про разные события?
                      • 785
                      • 2,113 Posts
                      При сохранении можно определить, сохраняется ли нужная страница, чтобы обновлять данные, а при загрузке обновлять придется каждый раз (так как неизвестно, менялись ли дочерние страницы), что менее эффективно. Но действительно можно привязать к событию OnDocFormPrerender и записать данные в таблицу site_tmplvars, откуда они сразу будут прочитаны. Только непонятно, зачем eval? Достаточно просто записать перечень элементов списка в таблицу.
                      По событиям – не знаю, где есть документация, я смотрю их в коде MODx.
                        Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
                        Статьи о MODx, регулярно новые публикации