Урок, на котором рассмотрим, как с помощью сниппетов pdoTools создать виджет, отображающий на сайте 5 самых популярных статей за последние 7 дней.

Описание виджета "Популярные статьи"

Виджет "Популярные статьи" предназначен для отображения на сайте 5 самых просматриваемых страниц за последние 7 дней.

MODX - Виджет "Популярные статьи"
Виджет популярных статей для сайта на MODX

Визуально данный виджет выполним в виде панели (компонента panel) front-end фреймворка Twitter Bootstrap. Содержимое панели организуем в виде нумерованного списка статей в порядке их убывания по количеству просмотров за неделю.

Необходимые компоненты

Рассматривать создание блока "Самое популярное" будем для сайта, в котором статьи организованы на базе компонента Tickets. По умолчанию просмотры тикетов в компоненте Tickets ведутся только для зарегистрированных пользователей. Для того чтобы просмотры регистрировались и для незарегистрированных посетителей, необходимо включить опцию "tickets.count_guests" в настройках.

MODX - Включение параметра "Считать просмотры страниц гостями"
Параметр Ticket, позволяющий учитывать просмотры страниц гостями

Кроме компонента Tickets, потребуется ещё компонент pdoTools. Данный компонент, содержит хороший набор сниппетов. В этой статье будем использовать из этого набора только сниппет pdoResources.

Таблицы TicketView и Ticket

Для создания запросов понадобятся 2 таблицы: TicketView и Ticket.

Первая таблица (TicketView) содержит записи о просмотренных пользователями тикетах. Она состоит из четырёх полей, но для выполнения запроса понадобятся только 2. Первое поле - это parent, оно хранит id просмотренного пользователем тикета. Второе поле - это timestamp, оно предназначено для хранения даты просмотра.

Вторая таблица (Ticket) будет основной. Она понадобится для того чтобы выбрать из неё необходимые ресурсы для которых будем подсчитывать количество просмотров.

Взаимосвязь между таблицами представим на следующей схеме:

MODX - Схема взаимосвязи таблиц Ticket и TicketView
MODX - Схема взаимосвязи таблиц Ticket и TicketView

Разработка виджета "Популярные статьи"

Создание виджета осуществим за 2 шага:

  1. Напишем сниппет getDateWeekAgo, который будет возвращать дату, которая была 7 дней назад.
  2. Выберем и выведем необходимые ресурсы с помощью сниппета pdoResources и getTicket. Сравним время и ресурсы, затрачиваемые ими на обработку.

Создание сниппета getDateWeekAgo

Для создания сниппетов необходимо открыть в левой панели администрирования вкладку "Элементы" и нажать на значок "+" напротив надписи "Сниппеты". В открывшейся странице ввести следующее:

  • в поле "Имя": getDateWeekAgo.
  • в поле "Код сниппета" следующий код:
    <?php
    $formatDate = date('Y-m-d H:i:s');
    $date = new DateTime($formatDate);
    $date->modify("-7 day");
    return $date->format('Y-m-d H:i:s');
MODX - Создание сниппета getDateWeekAgo
MODX - Создание сниппета getDateWeekAgo

Выборка записей с помощью сниппета pdoResources

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

<section class="panel panel-danger">
  <div class="panel-heading">
    <h5 class="panel-title">
      <i class="fa fa-heart"></i> <span title="Самые популярные статьи и уроки за последние 7 дней">Популярные статьи</span>
    </h5>
  </div>
  <div class="panel-body">
    [[!pdoResources?
      &loadModels=`tickets`
      &class=`Ticket`
      &leftJoin=`{
        "TicketView": {
          "class": "TicketView",
          "on": "Ticket.id = TicketView.parent"
        }
      }`
      &parents=`4`
      &where=`{"TicketView.timestamp:>":"[[!getDateWeekAgo]]"}`
      &select=`{
        "Ticket": "Ticket.id as id, Ticket.uri as uri, Ticket.pageTitle as pagetitle",
        "TicketView": "COUNT(TicketView.parent) as countviews"
      }`
      &hideContainers=`1`
      &groupby=`Ticket.id`
      &sortby=`{"countviews":"desc"}`
      &tpl=`@INLINE <p><span class="badge" style="background-color:#cc2929">[[+idx]]</span> <a href="[[+uri]]" style="color: #cc2929; vertical-align: middle;">[[+pagetitle]]</a> <span style="color: #cc2929;"><i class="fa fa-eye" style="vertical-align: middle;"></i><span style="vertical-align: middle;" title="Количество просмотров за последние 7 дней"> [[+countviews]]</span></span></p>`
      &limit=`5`
    ]]  
  </div>
</section>  
MODX - Лог работы pdoResources
MODX - Лог работы pdoResources

Выборка записей с помощью сниппета getTickets

В качестве 2 способа рассмотрим выборку данных и их отображение с помощью сниппета getTickets.

<section class="panel panel-danger">
  <div class="panel-heading">
    <h5 class="panel-title">
      <i class="fa fa-heart"></i> <span title="Самые популярные статьи и уроки за последние 7 дней">Популярные статьи</span>
    </h5>
  </div>
  <div class="panel-body">
    [[!getTickets?
      &leftJoin=`{
        "TicketView": {
          "class": "TicketView",
          "on": "Ticket.id = TicketView.parent"
        }
      }`
      &parents=`4`
      &where=`{"TicketView.timestamp:>":"[[!getDateWeekAgo]]"}`
      &select=`{
        "Ticket": "Ticket.id as id, Ticket.uri as uri, Ticket.pageTitle as pagetitle",
        "TicketView": "COUNT(TicketView.parent) as countviews"
      }`
      &hideContainers=`1`
      &groupby=`Ticket.id`
      &sortby=`{"countviews":"desc"}`
      &tpl=`@INLINE <p><span class="badge" style="background-color:#cc2929">[[+idx]]</span> <a href="[[+uri]]" style="color: #cc2929; vertical-align: middle;">[[+pagetitle]]</a> <span style="color: #cc2929;"><i class="fa fa-eye" style="vertical-align: middle;"></i><span style="vertical-align: middle;" title="Количество просмотров за последние 7 дней"> [[+countviews]]</span></span></p>`
      &limit=`5`
    ]]  
  </div>
</section>  
MODX - Лог работы getTickets
MODX - Лог работы getTickets
Поиск нужных ресурсов вышепредставленные сниппеты осуществляют с помощью параметра &parent. Т.е. для того чтобы настроить виджет "Популярные статьи" на свой сайт, Вам достаточно изменить значение 4 на необходимое.

Сравнение результатов работы сниппетов

Как видно из результатов логов, сниппет pdoResources выбирает данные намного быстрее. Это связано с тем, что в запросе участвуют только нужные таблицы. В то время как сниппет getTickets дополнительно подключает ещё классы (таблицы) TicketsSection, modUser и modUserProfile.