AjaxSnippet и HitsPage (REVO)
Здравствуйте. Вопрос вот в чем:
На странице в боковой колонке был реализован вызов getResources для отображения списка самых просматриваемых тем. Решил выводить через AjaxSnippet, но после выполнения сниппета не отрабатывает {%hp-[[+id]]%}. Вернее не отрабатывает сниппет HPCount, так как пользователю выводится {%hp-123%}. Вероятно нет инициализации HPCount вызываемом в футере. Может кто посоветует как выйти из этой ситуации?
На странице в боковой колонке был реализован вызов 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]]%} .....
Комментарии: 42
В шаблоне где реализован вызов сниппета getResources стоит вот это: [[!HPCount]]?
Ну так я же вроде написал. Да, есть вызов, прописан по дефолту в футере для всех страниц. Пытался даже вызывать прямо из чанка rating-lst сниппета getResources.
А если не ошибаюсь надо
[[!HPCount]]
указывать над выводом?
нет разницы это во первых. а во вторых, везде за исключением вывода через AjaxSnippet все отрабатывает корректно. Я уже не знаю в чем может быть причина… Да, [[!HPCount]] вызывал и совместно с AjaxSnippet и выше вызова. Безрезультатно.
Проблема в том, что не срабатывает плагин, который повешен на событие OnWebPagePrerender. А как вы понимаете, это событие не наступает при ajax'е.
Да, согласен… Даже не догадался посмотреть. Обыграть можно как то?
Наверно как-то можно. Указать параметр &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 отработает плейсхолдер или нет, нужно пробовать.Можно все сделать в одном сниппете. Если есть желание, то сам.
ajaxsnippet не хочет выводить результат в Placeholder. Или руки на столько кривые…
Пришлось лезть в код ajaxsnippet. Компонент состоит из сниппета и плагина, повешенного на событие OnLoadWebDocument. Из чего сделал вывод, что я ошибался насчет событий при ajax. События также выполняются. Но в данном случае, при ajax запросе плагин выполняется на событие OnLoadWebDocument и обрывает дальнейшее выполнение плагинов. Поэтому, плагин HitsPage не срабатывает на следующее событие OnWebPagePrerender.
Что тут можно сделать? Отредактировать плагин (а лучше скопировать под своим именем, чтоб при обновлении не затерлось) и внести перед строчкой в плагине AjaxSnippet'а
Что тут можно сделать? Отредактировать плагин (а лучше скопировать под своим именем, чтоб при обновлении не затерлось) и внести перед строчкой в плагине 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);
}
Решение, конечно, не очень красивое, но должно работать.
а просто приоритеты плагинам поставить не пробовали?
Володя, у меня встречный вопрос, а ты видел эти плагины AjaxSnippet и HitsPage?
AjaxSnippet да…
а в чем проблема?
а в чем проблема?
а в чем проблема?Посмотри и скажи мне. Я не большой спец по плагинам, помогаю чем могу.
просто замените
{%hp-[[+id]]%}
в шаблоне на[[!+properties.hitspage.hitts]]
и ничего не нужно менять…
+1.
Интересно, почему авторы HitsPage не предложили такое простое решение.
Интересно, почему авторы HitsPage не предложили такое простое решение.
При обычном вызове через getResources работает, но через AjaxSnippet не хочет.
замените уже getResources на pdoResources
или попробуйте без — !
то есть
то есть
[[+properties.hitspage.hitts]]
ну вот так же работает! что еще нужно то?
Такую портянку написали… Было бы из за чего…
Такую портянку написали… Было бы из за чего…
С удовольствием заменю, если подскажете как в pdo сделать сортировку по integer
&sortbyTVType=`integer`
&sortbyTV=`LikeDislike`
ТВ, по которому сортируется запрос должен быть типа «число» и ничего указывать не нужно.
Я уж молчу про продвинутую технику:
Я уж молчу про продвинутую технику:
&includeTVs=`LikeDislike `
&sortby=`CAST(TVlikedislike.value AS SIGNED INTEGER)`
Спасибо, отличное решение!
Мне еще учиться и учиться.
Мне еще учиться и учиться.
В общем объединили два плагина в 1)
Типа того. Работает?
Да, работает. Спасибо.
Если ты создал новый плагин, то исходный надо отключить.
Ну вы даёте.
Очень трудно написать плагин-обертку, который сначала вызовет HitsPage, а потом вернет ответ от get(pdo)Resources?
Очень трудно написать плагин-обертку, который сначала вызовет HitsPage, а потом вернет ответ от get(pdo)Resources?
:) Мне пока да.
Изменить плагин проще, да?
Вызов:
Сниппет MySnippetWrapper:
HitsPage я в глаза не видел, но по идее он должен выставить плейсхолдеры которые уже отработают в чанках pdoResources. Таким образом можно готовить информацию на вывод как угодно в своем сниппете.
Вызов:
[[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. Таким образом можно готовить информацию на вывод как угодно в своем сниппете.
HitsPage не выставляет плейсхолдеры, а выводит сразу число. Наверно, было бы удобно добивить туда такую возможность.
Я себе в шпаргалку записал твой код. Пригодится. :)
Я себе в шпаргалку записал твой код. Пригодится. :)
Если он выводит число, то можно так:
$number = $modx->runSnippet('HitsPage', $scriptProperties);
$output = $modx->runSnippet('pdoResources', $scriptProperties);
return str_replace('[[+плейсхолдер]]', $number, $output);
То есть, вручную заменяем нужный плейсхолдер числом от HitsPage.
За окном +32. Мозги плавятся. Я думал, что pdoResources в $output выводит все ресурсы, обернутые в чанк, в котором указан [[+плейсхолдер]]. Тогда у всех будет одно число или нет? Чего-то туго соображаю. :(
Еще раз повторяю, я не в курсе как работает HitsPage.
Если он должен выводить своё число для каждого ресурса — почему его нельзя вызвать прямо в чанке pdoResources?!
Народ так все галереи ресурсов, например, выводит на одной странице — просто вызывают в чанке
Я уж молчу про join таблицы HitsPage к ресурсу, чтобы вообще лишний раз сниппет не гонять.
Если он должен выводить своё число для каждого ресурса — почему его нельзя вызвать прямо в чанке pdoResources?!
Народ так все галереи ресурсов, например, выводит на одной странице — просто вызывают в чанке
[[ms2Gallery?resource=`[[+id]]`]]
Я уж молчу про join таблицы HitsPage к ресурсу, чтобы вообще лишний раз сниппет не гонять.
Так в чанке и стоит плейсхолдер {%hp-[[+id]]%}. Но он обрабатывается обрабатывается плагином на событие onWebpagePreRender. А твой плагин обрывает обработку после события OnLoadWebDocument. Вот он не не парсится.
Число просмотров пишется в таблицу ресурсов в поле properties.
П.С. Вот у ребят как описано hitspage
А вот плагин.
Число просмотров пишется в таблицу ресурсов в поле 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;
}
Алло, Сергей! Ты же написал:
А судя по этому комменту вообще нифига не нужно, потому что число хранится в поле ресурса, доступному по плейсхолдеру
В конце концов, вызовите pdoResources вообще без чанков и он распечатает весь ресурс — будет видно, откуда что брать.
HitsPage не выставляет плейсхолдеры, а выводит сразу число.Нафига нужен плейхолдер и плагин, если сниппет отдаёт готовое число?! Вызываешь сниппет в чанке — он выводит число и оно возвращается в оформлении pdoResources.
А судя по этому комменту вообще нифига не нужно, потому что число хранится в поле ресурса, доступному по плейсхолдеру
[[+properties.hitspage.hitts]]
Просто указываешь этот плейсхолдер в чанке pdoResources для документа и там будет значение.В конце концов, вызовите pdoResources вообще без чанков и он распечатает весь ресурс — будет видно, откуда что брать.
Алло, Сергей!Кто там? :)
Нафига нужен плейхолдер и плагин, если сниппет отдаёт готовое число?! Вызываешь сниппет в чанке — он выводит число и оно возвращается в оформлении pdoResources.Я тоже не понимаю для чего ребята из Artdevue это сделали (я ссылку на руководство давал в предыдущем комменте). Я тоже считаю, что проще было бы указать
[[+properties.hitspage.hitts]]
Но автор этого топика написал, что в ajax так не работает. Хотя должен по логике.
Вручную почистил весь кеш, заработало.
Я тоже считаю, что проще было бы указатьПри обычном выводе через pdoResources данные уходят в кеш и не обновляются. Через AjaxSnippet отрабатывает корректно.
[[+properties.hitspage.hitts]]
Одна голова хорошо, а 2 лучше.
P.S. А если указать с восклицательным знаком, то кэшироваться не должно
P.S. А если указать с восклицательным знаком, то кэшироваться не должно
[[!+properties.hitspage.hitts]]
Пробовал, все равно не обновляется.
тогда нужно сделать
Уже заменил на pdo. Больше вызовов getResources на сайте не осталось.
Для меня, да, на данный момент сложновато.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.