Решение: История просмотров на MODx Revo

Реализация сниппета, который бы выводил историю просмотренных страниц.

Ранее создавал "Вопрос" История просмотренных страниц на MODx Revo, в ней Василий Наумкин поделился ссылкой, на содержании данной ссылки, спустя время, написал сниппет.

Представляю к вашему вниманию.

Сниппет LastView:

<?php
$id = $modx->resource->id;

if (!isset($limit)) {$limit = 10;}
if (!isset($show)) {$show = 0;}
if (!isset($snippet)) {$snippet = 0;}
if (!isset($parents)) {$parents = 0;}
if (!isset($tpl)) {$tpl = 'tpl.LastView';}
if (!isset($except)) {$except = 0;} else {$except = split(",",$except);}

// Проверяем исключения
if($except != false) {
    $add = 1;
    foreach ($except as $value) {
        if($value == $id) {$add = 0;}
    }
}

// Добавляем просмотренную страницу
if ($add != false) {
    if (!isset($_SESSION['viewed'])) {
        $_SESSION['viewed'] = array($id);
    } else {
        if (in_array($id, $_SESSION['viewed'])) {
            $key = array_search($id, $_SESSION['viewed']);
            unset($_SESSION['viewed'][$key]);
        }

        if (count($_SESSION['viewed']) > $limit) {
            array_shift($_SESSION['viewed']);
        }
        
        $_SESSION['viewed'][] = $id;
    }
}

// Предварительные проверки
if ($show == '1') {
    if (!isset($_SESSION['viewed'])) {return;}
    $ids = array_reverse($_SESSION['viewed']);
    if (empty($ids)) {return;}
}

// Выводим просмотренные страницы без вызова сниппета
if ($show == '1' && $snippet == false) {
    $output = '';
    foreach ($ids as $tsID) {
        if($tsID != $id) {
            $page = $modx->getObject('modResource', $tsID)->toArray();
            $output .= $modx->getChunk($tpl, $page);
        }
    }
    return $output;
}

// Выводим просмотренные страницы через вызов сниппета
if ($show == '1'  && $snippet != false) {
    $config = array(
         'resources' => '-'.$id.','.implode(',', $ids)
        ,'parents' => $parents
        ,'limit' => $limit
        ,'tpl' => $tpl
    );
    return $modx->runSnippet($snippet, $config);
}

пример вызова:

[[!LastView? &limit=`10` &show=`1` &snippet=`0` &parents=`0` &tpl=`tpl.LastView` &except=`[[++site_start]],404,502`]]

пример шаблона tpl.LastView:

<a href="[[~[[+id]]]]">[[+pagetitle]]</a>

так же можно использовать вывод любых других данных документа

доступные значения:

  • &limit - лимит отображаемых и записываемых id страниц, по умолчанию 10

  • &show - отображать страницы или нет (0/1), по умолчанию 0 (будет записывать, но не отображать)

  • &snippet - наименование сниппета, с помощью которого будут выводиться данные (pdoResources, getResources и т.п.), по умолчанию 0 (false, то будет выводить данные с помощью modResource)

  • &parents - id родительского документа, по умолчанию 0

  • &tpl - наименования чанка с шаблоном, по умолчанию tpl.LastView.

  • &except - id исключаемых документов через запятую, по умолчанию 0.

Мой пример: Проект про офтальмологию (История просмотров, перед футером страницы)

.

-- Вот и всё, возможно кому нибудь пригодится

← Предыдущая заметка
Вывод секций для публикаций Tickets
Следующая заметка →
Переключение контекстов в зависимости от URL
Комментарии (25)
asxАлександр Котлов
07.10.2013 18:15

Большое спасибо!

LEONesoПавел Левин
07.10.2013 18:40

Всегда пожалуйста

inetloverАлександр Наумов
07.10.2013 19:01

Спасибо за сниппет!!

asxАлександр Котлов
07.10.2013 19:04

А если еще в начало вставвить


if (!isset($thumbs)) {$thumbs = '120x90';}</b>

а в конец


,'tpl' => $tpl
 ,'includeThumbs' => $thumbs,

то он будет отлично выводить картинку просмотренного товара минишоп)

Антон СоловьёвАнтон Соловьёв
08.10.2013 11:21

прощения за офтоп, но зачем на сайте куркод, что даёт? я не собираюсь холифарить, просто короткий ответ.

LEONesoПавел Левин
08.10.2013 12:14

В смартфонах есть функция распознания qr-кода, соответственно можно спокойно сфоткать монитор или распечатку с qr-кодом и перейти на страницу, в данном примере, каждая страница имеет свой qr-код, в котором url текущей страницы. Пока мобильной версии нет, но планируется.

Пользователи разные бывают :-)

Антон СоловьёвАнтон Соловьёв
08.10.2013 12:21

Но если они уже в интернете на стационарном компе, зачем и с мобилы входить? продолжить чтение в транспорте типа?

mvoevodskiyВоеводский Михаил
08.10.2013 12:29

Можно в транспорте, а можно на мобильнике оставить открытым окно с контактами, когда собираешься ехать в эту компанию. Ситуации бывают разные :)

Антон СоловьёвАнтон Соловьёв
08.10.2013 12:38

Спасибо. Наконец-то дошло )

LEONesoПавел Левин
08.10.2013 14:41

Поправил код, добавив исключение текущей страницы из вывода.

Mihan
13.11.2013 21:25

Отличное решение, спасибо.

Вывожу перед сниппетом текст "Вы недавно смотрели:". Не подскажете, как скрывать его, если массив пустой?

LEONesoПавел Левин
14.11.2013 14:53

Можно дописать скрипт:

// Предварительные проверки
if ($show == '1') {
    if (!isset($_SESSION['viewed'])) {return;}
    $ids = array_reverse($_SESSION['viewed']);
    if (empty($ids)) {return;}
    echo '<h3>Вы недавно смотрели:</h3>';//заголовок
}
Александр Москвин
14.11.2013 12:22

Что-то сайт подтормаживает. 3.9 секунды одну страницу открывает, потом 0.69.

Когда я делал сайт http://tokyorope.ru/ - я максимально увеличил скорость генерации, сам можешь заценить.

LEONesoПавел Левин
14.11.2013 14:50

На сайте громоздкое меню, плюс проверка нового, в отличии от меню, проверка нового не кэшируется. В остальном пока думаю, что делать, много фильтров использовано.

Вадим Еременко
21.04.2014 11:02

Добрый день! Сниппет работает отлично, но один момент никак не пойму - как подключить вывод ТВ параметров? В частности нужно изображение и цена... Просьба сильно ногами не пинать - первый проект на Revo) Спасибо)

Aleksey
04.07.2014 13:49

Добрый день, у вас получилось сделать вывод ТВ?

Aleksey
04.07.2014 13:48

Всем доброго дня, а как сделать чтобы тв параметры из шаблона тоже парсились? Заранее спасибо за ответ

LEONesoПавел Левин
04.07.2014 14:02

Мне кажется вам сюда. Думаю речь идет о товарах?

Aleksey
04.07.2014 14:14

Да речь о товарах. По ссылке, что вы прислали про тв ничего нет.

LEONesoПавел Левин
04.07.2014 15:07

Там есть упоминания в коде. --

Template VariablesGetting the processed value of a TV from the current document (or any document you have a reference to) is easy with this method (note that both instances of the letter 'V' in getTVValue() are capitalized):

$val = $modx->resource->getTVValue('name_of_tv');
$val = $modx->resource->getTVValue($id); // ID of the TV (not the document)

or

$resource = $modx->getObject('modResource',array('pagetitle'=>'SomePage'));
$val = $resource->getTVValue('name_of_tv');
$val = $resource->getTVValue($id); // ID of the TV (not the document)

Getting the value of a TV in another document is a little more tricky because the processed value of the TV can be different for each document it's embedded in. As a result, you have to either get the resource object using the method above, or use specific methods of the TV and send along the ID of the document. Assuming that $id is the ID of the document (not the TV):

/* Get the TV */
$tv = $modx->getObject('modTemplateVar',array('name'=>'MyTV'));

/* get the raw content of the TV */
$rawValue = $tv->getValue($id);

/* get the processed content of the TV */
$processedValue = $tv->renderOutput($id);
Aleksey
04.07.2014 15:20

спасибо огромное

LEONesoПавел Левин
04.07.2014 15:20

По идее. Просто надо дописать необходимые параметры в массив согласно документации сниппета и вызывать через pdoResources или getResources, самый простой вариант:

// Выводим просмотренные страницы через вызов сниппета
if ($show == '1'  && $snippet != false) {
    $config = array(
         'resources' => '-'.$id.','.implode(',', $ids)
        ,'parents' => $parents
        ,'limit' => $limit
        ,'tpl' => $tpl
        ,'includeTVs' => '1'
        ,'includeTVList'='image,price'//необходимые поля для вывода
    );
    return $modx->runSnippet($snippet, $config);
}
Саша Иващенко
21.07.2014 03:52

а как не показывать каталоги? а оставить только документы

LEONesoПавел Левин
21.07.2014 09:41

Думаю если поставить после

,'tpl' => $tp

эту строку

,'isfolder' => ''

То каталоги, которые имеют значение "1" не будут выводиться. Не знаю точно, возможно там и "0" в место пустоты, надо пробовать. Можно поиграть с 'true' и 'false'

LEONesoПавел Левин
21.07.2014 09:47

Хотя ,если получше подумать, стоит прервать добавление в список страниц.

За основу возьмем этот код:

<?php
if ($modx->resource->get('isfolder')) {
    $output .= "It's marked as a container</p>";
}
 
if ($modx->resource->hasChildren()) {
 
$output .= "<p>This document has Children</p>";
}
 
return $output;
?>

и вставим

$modx->resource->get('isfolder')

внутрь условия

if ($add != false) {

получаем

if ($add != false && !$modx->resource->get('isfolder')) {

В результате, каталоги не пройдут в список истории просмотра. Должно работать =)

bezumkin
Василий Наумкин
09.04.2024 01:45
Ошибка 500 Это не похоже на ошибку Nginx, это скорее всего ошибка PHP - надо смотреть его логи. Во...
futuris
Futuris
04.04.2024 05:56
Я просто немного запутался. Когда в абзаце &quot;Vesp/Core&quot; ты пишешь про &quot;новый trait Fil...
bezumkin
Василий Наумкин
20.03.2024 18:21
Volledig!
Андрей
14.03.2024 10:47
Василий! Как всегда очень круто! Моё почтение!
russelgal
russel gal
09.03.2024 17:17
А этот стоило написать хотя бы затем, чтобы получить комментарий от юзера, который ничего не писал ...
inetlover
Александр Наумов
27.01.2024 00:06
Василий, спасибо! Извини, тупанул.
bezumkin
Василий Наумкин
22.01.2024 04:43
Давай-давай!
bezumkin
Василий Наумкин
24.12.2023 11:26
Спасибо!
bezumkin
Василий Наумкин
27.11.2023 02:43
Ура!
bezumkin
Василий Наумкин
25.11.2023 08:30
Vesp тянет 2 зависимости: vesp-frontent для фронта и vesp-core для бэкенда. Их можно обновлять, но э...