AjaxSnippet и HitsPage (REVO)

Здравствуйте. Вопрос вот в чем:
На странице в боковой колонке был реализован вызов getResources для отображения списка самых просматриваемых тем. Решил выводить через AjaxSnippet, но после выполнения сниппета не отрабатывает {%hp-[[+id]]%}. Вернее не отрабатывает сниппет HPCount, так как пользователю выводится {%hp-123%}. Вероятно нет инициализации HPCount вызываемом в футере. Может кто посоветует как выйти из этой ситуации?
[[AjaxSnippet?
&snippet=`getResources`
&parents=`.....`
&tpl=`rating-lst` 
&showHidden=`0` 
&includeTVs=`LikeDislike` 
&tvPrefix=``
&sortbyTVType=`integer`
&sortbyTV=`LikeDislike`
&limit=`5`
&as_mode=`onload`
]]
чанк rating-lst
.... Просмотров: {%hp-[[+id]]%} .....
Александр
30 июля 2014, 07:40
modx.pro
2
2 110
0

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

Андрей
31 июля 2014, 07:48
0
В шаблоне где реализован вызов сниппета getResources стоит вот это: [[!HPCount]]?
    Александр
    31 июля 2014, 08:34
    0
    Ну так я же вроде написал. Да, есть вызов, прописан по дефолту в футере для всех страниц. Пытался даже вызывать прямо из чанка rating-lst сниппета getResources.
    Михаил
    31 июля 2014, 09:23
    0
    А если не ошибаюсь надо
    [[!HPCount]]
    указывать над выводом?
      Александр
      31 июля 2014, 09:38
      0
      нет разницы это во первых. а во вторых, везде за исключением вывода через AjaxSnippet все отрабатывает корректно. Я уже не знаю в чем может быть причина… Да, [[!HPCount]] вызывал и совместно с AjaxSnippet и выше вызова. Безрезультатно.
        Сергей Шлоков
        31 июля 2014, 09:43
        +1
        Проблема в том, что не срабатывает плагин, который повешен на событие OnWebPagePrerender. А как вы понимаете, это событие не наступает при ajax'е.
          Александр
          31 июля 2014, 10:41
          0
          Да, согласен… Даже не догадался посмотреть. Обыграть можно как то?
            Сергей Шлоков
            31 июля 2014, 11:24
            0
            Наверно как-то можно. Указать параметр &toPlaceholder=`MyPlaceholder`. А потом разобрать его в своем сниппете, например, HPCount (код можно взять из плагина Hitspage).
            $output = $modx->getPlaceholder('MyPlaceholder');
            if (preg_match_all ("/{%hp-(.*?)%}/",$output , $hp_list)) {
            // If the array is not empty, choose the number of comments on the resource id (column rid)
            	if (is_array($hp_list)) {
            		 array_walk($hp_list[1], 'intval');
            		  $hp = $modx->newQuery('modResource', array('id:IN' => $hp_list[1]));
            		  $hp->select(array('modResource.id','modResource.properties'));
            		  if ($hp->prepare() && $hp->stmt->execute()) {
            			  $resultsHp = $hp->stmt->fetchAll(PDO::FETCH_ASSOC);
            			  foreach ($resultsHp as $rHp) {
            				  $objHP = json_decode($rHp['properties']);
            				  if (in_array($rHp['id'],$hp_list[1])) {
            					  $hp_list[1][array_search($rHp['id'],$hp_list[1])] =  intval($objHP->hitspage->hitts);
            				  }
            			  }
            		  }
            	  }
            	  // Replace all your templates in the resource to the correct values
            	  $output = str_replace($hp_list[0], $hp_list[1], $output);
            	$modx->setPlaceholder('MyPlaceholder',$output);
            }

            А вызывать так
            [[ajaxsnippet ....]] 
            [[!HPCount ]]
            [[+MyPlaceholder]]
            Не проверял. Может нужно пилить. Только я не знаю, AjaxSnippet отработает плейсхолдер или нет, нужно пробовать.
            Можно все сделать в одном сниппете. Если есть желание, то сам.
              Александр
              31 июля 2014, 11:50
              0
              ajaxsnippet не хочет выводить результат в Placeholder. Или руки на столько кривые…
                Сергей Шлоков
                31 июля 2014, 12:20
                +1
                Пришлось лезть в код ajaxsnippet. Компонент состоит из сниппета и плагина, повешенного на событие OnLoadWebDocument. Из чего сделал вывод, что я ошибался насчет событий при ajax. События также выполняются. Но в данном случае, при ajax запросе плагин выполняется на событие OnLoadWebDocument и обрывает дальнейшее выполнение плагинов. Поэтому, плагин HitsPage не срабатывает на следующее событие OnWebPagePrerender.
                Что тут можно сделать? Отредактировать плагин (а лучше скопировать под своим именем, чтоб при обновлении не затерлось) и внести перед строчкой в плагине AjaxSnippet'а
                $response = array(
                	'output' => $output,
                	'key' => $_REQUEST['as_action'],
                	'snippet' => $scriptProperties['snippet'],
                );
                вот этот код
                if (preg_match_all ("/{%hp-(.*?)%}/",$output , $hp_list)) {
                // If the array is not empty, choose the number of comments on the resource id (column rid)
                	if (is_array($hp_list)) {
                		 array_walk($hp_list[1], 'intval');
                		  $hp = $modx->newQuery('modResource', array('id:IN' => $hp_list[1]));
                		  $hp->select(array('modResource.id','modResource.properties'));
                		  if ($hp->prepare() && $hp->stmt->execute()) {
                			  $resultsHp = $hp->stmt->fetchAll(PDO::FETCH_ASSOC);
                			  foreach ($resultsHp as $rHp) {
                				  $objHP = json_decode($rHp['properties']);
                				  if (in_array($rHp['id'],$hp_list[1])) {
                					  $hp_list[1][array_search($rHp['id'],$hp_list[1])] =  intval($objHP->hitspage->hitts);
                				  }
                			  }
                		  }
                	  }
                	  // Replace all your templates in the resource to the correct values
                	  $output = str_replace($hp_list[0], $hp_list[1], $output);
                }
                Решение, конечно, не очень красивое, но должно работать.
                  Володя
                  31 июля 2014, 12:24
                  0
                  а просто приоритеты плагинам поставить не пробовали?
                    Сергей Шлоков
                    31 июля 2014, 12:38
                    0
                    Володя, у меня встречный вопрос, а ты видел эти плагины AjaxSnippet и HitsPage?
                      Володя
                      31 июля 2014, 12:39
                      0
                      AjaxSnippet да…
                      а в чем проблема?
                        Сергей Шлоков
                        31 июля 2014, 12:49
                        0
                        а в чем проблема?
                        Посмотри и скажи мне. Я не большой спец по плагинам, помогаю чем могу.
                        Володя
                        31 июля 2014, 13:12
                        1
                        +1
                        просто замените
                        {%hp-[[+id]]%}
                        в шаблоне на
                        [[!+properties.hitspage.hitts]]
                        и ничего не нужно менять…
                        Сергей Шлоков
                        31 июля 2014, 13:16
                        0
                        +1.
                        Интересно, почему авторы HitsPage не предложили такое простое решение.
                        Александр
                        31 июля 2014, 13:29
                        0
                        При обычном вызове через getResources работает, но через AjaxSnippet не хочет.
                        Володя
                        31 июля 2014, 13:36
                        0
                        замените уже getResources на pdoResources
                        Володя
                        31 июля 2014, 13:38
                        0
                        или попробуйте без — !
                        то есть
                        [[+properties.hitspage.hitts]]
                        Володя
                        31 июля 2014, 15:13
                        0
                        ну вот так же работает! что еще нужно то?
                        Такую портянку написали… Было бы из за чего…
                        Александр
                        31 июля 2014, 13:56
                        0
                        С удовольствием заменю, если подскажете как в pdo сделать сортировку по integer

                        &sortbyTVType=`integer`
                        &sortbyTV=`LikeDislike`
                        Василий Наумкин
                        31 июля 2014, 14:52
                        +1
                        ТВ, по которому сортируется запрос должен быть типа «число» и ничего указывать не нужно.

                        Я уж молчу про продвинутую технику:
                        &includeTVs=`LikeDislike `
                        &sortby=`CAST(TVlikedislike.value AS SIGNED INTEGER)`
                        Александр
                        31 июля 2014, 15:32
                        0
                        Спасибо, отличное решение!
                        Мне еще учиться и учиться.
                  Александр
                  31 июля 2014, 12:41
                  0
                  В общем объединили два плагина в 1)
    Василий Наумкин
    31 июля 2014, 12:52
    0
    Ну вы даёте.

    Очень трудно написать плагин-обертку, который сначала вызовет HitsPage, а потом вернет ответ от get(pdo)Resources?
      Сергей Шлоков
      31 июля 2014, 13:03
      0
      :) Мне пока да.
        Василий Наумкин
        31 июля 2014, 13:38
        1
        0
        Изменить плагин проще, да?

        Вызов:
        [[AjaxSnippet?
        &snippet=`MySnippetWrapper`
        &parents=`.....`
        &tpl=`rating-lst` 
        &showHidden=`0` 
        &includeTVs=`LikeDislike` 
        &tvPrefix=``
        &sortbyTVType=`integer`
        &sortbyTV=`LikeDislike`
        &limit=`5`
        &as_mode=`onload`
        ]]

        Сниппет MySnippetWrapper:
        <?php
        $modx->runSnippet('HitsPage', $scriptProperties);
        
        return $modx->runSnippet('pdoResources', $scriptProperties)

        HitsPage я в глаза не видел, но по идее он должен выставить плейсхолдеры которые уже отработают в чанках pdoResources. Таким образом можно готовить информацию на вывод как угодно в своем сниппете.
          Сергей Шлоков
          31 июля 2014, 14:49
          0
          HitsPage не выставляет плейсхолдеры, а выводит сразу число. Наверно, было бы удобно добивить туда такую возможность.
          Я себе в шпаргалку записал твой код. Пригодится. :)
            Василий Наумкин
            31 июля 2014, 14:55
            1
            0
            Если он выводит число, то можно так:
            $number = $modx->runSnippet('HitsPage', $scriptProperties);
            $output = $modx->runSnippet('pdoResources', $scriptProperties);
            
            return str_replace('[[+плейсхолдер]]', $number, $output);
            То есть, вручную заменяем нужный плейсхолдер числом от HitsPage.
              Сергей Шлоков
              31 июля 2014, 15:01
              1
              0
              За окном +32. Мозги плавятся. Я думал, что pdoResources в $output выводит все ресурсы, обернутые в чанк, в котором указан [[+плейсхолдер]]. Тогда у всех будет одно число или нет? Чего-то туго соображаю. :(
                Василий Наумкин
                31 июля 2014, 15:04
                0
                Еще раз повторяю, я не в курсе как работает HitsPage.

                Если он должен выводить своё число для каждого ресурса — почему его нельзя вызвать прямо в чанке pdoResources?!
                Народ так все галереи ресурсов, например, выводит на одной странице — просто вызывают в чанке
                [[ms2Gallery?resource=`[[+id]]`]]

                Я уж молчу про join таблицы HitsPage к ресурсу, чтобы вообще лишний раз сниппет не гонять.
                  Сергей Шлоков
                  31 июля 2014, 15:14
                  0
                  Так в чанке и стоит плейсхолдер {%hp-[[+id]]%}. Но он обрабатывается обрабатывается плагином на событие onWebpagePreRender. А твой плагин обрывает обработку после события OnLoadWebDocument. Вот он не не парсится.
                  Число просмотров пишется в таблицу ресурсов в поле properties.
                  П.С. Вот у ребят как описано hitspage
                  А вот плагин.
                  <?php
                  switch ($modx->event->name) {
                      case 'OnWebPagePrerender':
                          if($modx->hpCount === true) {
                              // get a reference to the output
                  			$output = &$modx->resource->_output;
                      		if (preg_match_all ("/{%hp-(.*?)%}/",$output , $hp_list)) {
                  			  // If the array is not empty, choose the number of comments on the resource id (column rid)
                  			  if (is_array($hp_list)) {
                  				  array_walk($hp_list[1], 'intval');
                  				  $hp = $modx->newQuery('modResource', array('id:IN' => $hp_list[1]));
                  				  $hp->select(array('modResource.id','modResource.properties'));
                  				  if ($hp->prepare() && $hp->stmt->execute()) {
                  					  $resultsHp = $hp->stmt->fetchAll(PDO::FETCH_ASSOC);
                  					  foreach ($resultsHp as $rHp) {
                  						  $objHP = json_decode($rHp['properties']);
                  						  if (in_array($rHp['id'],$hp_list[1])) {
                  							  $hp_list[1][array_search($rHp['id'],$hp_list[1])] =  intval($objHP->hitspage->hitts);
                  						  }
                  					  }
                  				  }
                  			  }
                  			  // Replace all your templates in the resource to the correct values
                  			  $output = str_replace($hp_list[0], $hp_list[1], $output);
                  		  }
                          }
                      break;
                  }
                    Василий Наумкин
                    31 июля 2014, 15:18
                    0
                    Алло, Сергей! Ты же написал:
                    HitsPage не выставляет плейсхолдеры, а выводит сразу число.
                    Нафига нужен плейхолдер и плагин, если сниппет отдаёт готовое число?! Вызываешь сниппет в чанке — он выводит число и оно возвращается в оформлении pdoResources.

                    А судя по этому комменту вообще нифига не нужно, потому что число хранится в поле ресурса, доступному по плейсхолдеру
                    [[+properties.hitspage.hitts]]
                    Просто указываешь этот плейсхолдер в чанке pdoResources для документа и там будет значение.

                    В конце концов, вызовите pdoResources вообще без чанков и он распечатает весь ресурс — будет видно, откуда что брать.
                      Сергей Шлоков
                      31 июля 2014, 15:42
                      0
                      Алло, Сергей!
                      Кто там? :)
                      Нафига нужен плейхолдер и плагин, если сниппет отдаёт готовое число?! Вызываешь сниппет в чанке — он выводит число и оно возвращается в оформлении pdoResources.
                      Я тоже не понимаю для чего ребята из Artdevue это сделали (я ссылку на руководство давал в предыдущем комменте). Я тоже считаю, что проще было бы указать
                      [[+properties.hitspage.hitts]]
                      Но автор этого топика написал, что в ajax так не работает. Хотя должен по логике.
                        Александр
                        31 июля 2014, 15:49
                        0
                        Вручную почистил весь кеш, заработало.
                        Я тоже считаю, что проще было бы указать
                        [[+properties.hitspage.hitts]]
                        При обычном выводе через pdoResources данные уходят в кеш и не обновляются. Через AjaxSnippet отрабатывает корректно.
                        Сергей Шлоков
                        31 июля 2014, 15:55
                        0
                        Одна голова хорошо, а 2 лучше.
                        P.S. А если указать с восклицательным знаком, то кэшироваться не должно
                        [[!+properties.hitspage.hitts]]
                        Александр
                        31 июля 2014, 15:56
                        0
                        Пробовал, все равно не обновляется.
                        Володя
                        31 июля 2014, 15:57
                        0
                        тогда нужно сделать
                        Александр
                        31 июля 2014, 16:09
                        +1
                        Уже заменил на pdo. Больше вызовов getResources на сайте не осталось.
      Александр
      31 июля 2014, 13:03
      0
      Для меня, да, на данный момент сложновато.
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      42