pdoPage — постраничная навигация и пагинация для MODX

Дополнения

Сниппет pdoPage предназначен для вывода результатов работы других сниппетов с разбивкой на страницы. Он является улучшенной альтернативой стандартному getPage и генерирует более правильную пагинацию, защищая сайт от некорректных запросов в параметрах page и limit. Основное преимущество pdoPage заключается в корректной работе с SEO-дружественными URL и встроенной поддержке AJAX для динамической подгрузки страниц без перезагрузки.

Сниппет работает как обертка над любым другим сниппетом через параметр &element, либо напрямую с pdoResources если параметр не указан. Важная особенность — вызов должен быть некешируемым, иначе возникнут проблемы при переключении страниц.

пример пагинаций

Параметры pdoPage

При вызове сниппета pdoPage указываются параметры сниппета, для которого производится пагинация. Данный сниппет должен понимать параметры &page и &limit. По умолчанию pdoPage принимает все параметры pdoTools и кроме того, некоторые свои:

Параметры пагинации

Параметр Значение по умолчанию Описание
&element pdoResources Имя сниппета для пагинации
&limit 10 Количество элементов на одной странице
&maxLimit 100 Максимально допустимый лимит (защита от перегрузки)
&offset 0 Начальное смещение для выборки
&page 1 Номер стартовой страницы
&pageVarKey page Имя GET-параметра для номера страницы
&pageLimit 5 Количество видимых ссылок на страницы (≥7 для продвинутого режима)
&pageNavVar page.nav Имя плейсхолдера для HTML пагинации
&pageCountVar pageCount Плейсхолдер для общего количества страниц
&pageLinkScheme Схема генерации ЧПУ ссылок на страницы
&totalVar page.total Плейсхолдер для общего количества результатов
&cache 0 Включить кеширование результатов
&cacheTime 3600 Время жизни кеша в секундах
&cache_user Принудительный ID пользователя для кеша
&toPlaceholder Сохранить вывод в плейсхолдер
&plPrefix Префикс для всех плейсхолдеров
&strictMode 1 Строгий режим с редиректами на корректные страницы
&setMeta 1 Добавлять мета-теги rel=»prev/next» для SEO

Параметры Ajax

Параметр Значение по умолчанию Описание
&ajax 0 Включить поддержку Ajax запросов
&ajaxMode Режим Ajax пагинации: default, button или scroll
&ajaxElemWrapper #pdopage jQuery селектор обертки с результатами
&ajaxElemRows #pdopage .rows Селектор блока с результатами
&ajaxElemPagination #pdopage .pagination Селектор блока пагинации
&ajaxElemLink #pdopage .pagination a Селектор ссылок пагинации
&ajaxElemMore #pdopage .btn-more Селектор кнопки «показать еще»
&ajaxHistory 0 Сохранять номер страницы в URL при Ajax
&frontend_js путь к pdopage.min.js Путь к JavaScript файлу
&frontend_css путь к pdopage.min.css Путь к CSS файлу стилей

Шаблоны пагинации

Параметр Значение по умолчанию Описание
&tplPage @INLINE <li><a href="[[+href]]">[[+pageNo]]</a></li> Чанк для обычной ссылки на страницу
&tplPageWrapper @INLINE <div class="pagination"><ul class="pagination">[[+first]][[+prev]][[+pages]][[+next]][[+last]]</ul></div> Обертка всей пагинации с плейсхолдерами навигации
&tplPageActive @INLINE <li class="active"><a href="[[+href]]">[[+pageNo]]</a></li> Чанк для текущей активной страницы
&tplPageFirst @INLINE <li class="control"><a href="[[+href]]">[[%pdopage_first]]</a></li> Ссылка на первую страницу
&tplPageLast @INLINE <li class="control"><a href="[[+href]]">[[%pdopage_last]]</a></li> Ссылка на последнюю страницу
&tplPagePrev @INLINE <li class="control"><a href="[[+href]]">&laquo;</a></li> Ссылка на предыдущую страницу
&tplPageNext @INLINE <li class="control"><a href="[[+href]]">&raquo;</a></li> Ссылка на следующую страницу
&tplPageSkip @INLINE <li class="disabled"><span>...</span></li> Заполнитель для пропущенных страниц (…)
&tplPageFirstEmpty @INLINE <li class="control"><span>[[%pdopage_first]]</span></li> Чанк при отсутствии первой страницы
&tplPageLastEmpty @INLINE <li class="control"><span>[[%pdopage_last]]</span></li> Чанк при отсутствии последней страницы
&tplPagePrevEmpty @INLINE <li class="disabled"><span>&laquo;</span></li> Чанк при отсутствии предыдущей страницы
&tplPageNextEmpty @INLINE <li class="disabled"><span>&raquo;</span></li> Чанк при отсутствии следующей страницы
&ajaxTplMore @INLINE <button class="btn btn-default btn-more">[[%pdopage_more]]</button> Чанк кнопки «загрузить еще» для режима button

Примеры использования

Простейший вызов pdoPage для вывода ресурсов с пагинацией:

[[!pdoPage?
&parents=`[[*id]]`
&tpl=`tpl.chunk`
&limit=`5`
]]
[[!+page.nav]]

Обратите внимание что сниппет вызывается некешируемым через восклицательный знак, а навигация выводится отдельным плейсхолдером [[!+page.nav]].

Основные параметры настройки

Параметры пагинации

Параметр &limit определяет количество элементов на одной странице. По умолчанию 10 элементов:

[[!pdoPage? &parents=`5` &limit=`20`]]

Параметр &offset позволяет пропустить указанное количество результатов от начала. Это полезно когда нужно вывести первые элементы отдельно:

[[!pdoPage? &parents=`5` &offset=`3` &limit=`10`]]

Параметры URL и переменных

Параметр &pageVarKey определяет имя переменной в URL для номера страницы. По умолчанию page:

[[!pdoPage? &parents=`5` &pageVarKey=`news`]]

В этом случае URL будет выглядеть как ?news=2 вместо ?page=2.

Параметр &pageNavVar задает имя плейсхолдера для вывода навигации. По умолчанию page.nav:

[[!pdoPage?
&parents=`5`
&pageVarKey=`news`
]]

Параметр &totalVar определяет имя плейсхолдера для сохранения общего количества результатов:

[[!pdoPage?
&parents=`5`
&totalVar=`total`
]]
Всего найдено: [[!+total]] элементов

Параметры внешнего вида

[[!pdoPage?
&parents=`5`
&tplPage=`@INLINE <li><a href="[[+href]]">[[+pageNo]]</a></li>`
&tplPageActive=`@INLINE <li class="active"><span>[[+pageNo]]</span></li>`
&tplPageWrapper=`@INLINE <div class="pagination"><ul>[[+first]][[+prev]][[+pages]][[+next]][[+last]]</ul></div>`
]]
  • Параметр &tplPage определяет шаблон для обычной ссылки на страницу.
  • Параметр &tplPageActive задает шаблон для активной (текущей) страницы.
  • Параметр &tplPageWrapper оборачивает всю навигацию в контейнер.

Настройка элементов навигации

Пропуск страниц

Параметр &pageLimit определяет максимальное количество ссылок на страницы в навигации. По умолчанию 5:

[[!pdoPage?
&parents=`5`
&pageLimit=`7`
]]

Если страниц больше чем указано в &pageLimit, появятся ссылки для пропуска.

Параметр &tplPageSkip задает шаблон для пропуска страниц:

[[!pdoPage?
&parents=`5`
&pageLimit=`5`
&tplPageSkip=`@INLINE <li class="skip"><span>...</span></li>`
]]

Несколько пагинаций на одной странице

PdoPage поддерживает размещение нескольких независимых пагинаций на одной странице. Для этого нужно переопределить параметры &pageVarKey и &pageNavVar для каждого вызова.

Первая пагинация для новостей:

[[!pdoPage?
&parents=`10`
&pageVarKey=`news`
&pageNavVar=`news.nav`
&limit=`5`
&tpl=`newsTpl`
]]
[[!+news.nav]]

Вторая пагинация для статей:

[[!pdoPage?
&parents=`20`
&pageVarKey=`articles`
&pageNavVar=`articles.nav`
&limit=`10`
&tpl=`articleTpl`
]]
[[!+articles.nav]]

Как видите, для работы нескольких пагинаций на одной странице достаточно просто переопределить пару параметров.

AJAX пагинация

PdoPage умеет загружать страницы через AJAX без перезагрузки всей страницы. Для этого нужно обернуть вызов сниппета в специальную разметку.

Базовая настройка AJAX пагинации:

<div id="pdopage">
  <div class="rows">
    [[!pdoPage?
    &parents=`5`
    &ajaxMode=`default`
    &limit=`10`
    &tpl=`itemTpl`
    ]]
  </div>
  [[!+page.nav]]
</div>

Параметр &ajaxMode включает AJAX режим. Возможные значения:

  • default — стандартный режим с историей браузера
  • button — подгрузка по кнопке «Показать еще»
  • scroll — автоматическая подгрузка при прокрутке

Важно чтобы контейнер имел атрибут id="pdopage", а результаты были обернуты в элемент с классом rows.

Пример с кнопкой «Показать еще»:

<div id="pdopage">
  <div class="rows">
    [[!pdoPage?
    &parents=`5`
    &ajaxMode=`button`
    &limit=`6`
    ]]
  </div>
  <button class="btn-more">Показать еще</button>
  [[!+page.nav]]
</div>

Для правильной работы AJAX-фильтров обязательно добейтесь чтобы нормально работала AJAX-пагинация, потому что своих механизмов работы с AJAX писать не нужно — используются встроенные методы pdoPage.

ЧПУ для пагинации

PdoPage по умолчанию генерирует URL с GET-параметрами типа ?page=2. Для создания SEO-дружественных URL вида /page/2/ нужно использовать плагин на событии OnPageNotFound.

Создайте новый плагин на событие OnPageNotFound:

<?php
// Получаем переменную запроса из системной настройки
$pageVarKey = $modx->getOption('pdoPage.page_var', null, 'page', true);

// Получаем URI страницы
$uri = trim($modx->getOption('request_uri', $_REQUEST, $_SERVER['REQUEST_URI']), '/');

// Ищем номер страницы в URI
if (preg_match('/(.*?)\/' . $pageVarKey . '\/([\d]+)\/?$/i', $uri, $matches)) {
    // Ищем ресурс по адресу без номера страницы
    $id = $modx->findResource(rtrim($matches[1], '/'));
    
    // Если ресурс найден
    if ($id) {
        // Добавляем номер страницы в глобальные массивы
        $_GET[$pageVarKey] = $_REQUEST[$pageVarKey] = $matches[2];
        // Загружаем эту страницу
        $modx->sendForward($id);
    }
}

После этого пагинация будет работать с красивыми URL вида /catalog/page/2/.

Использование наборов параметров

Для удобства переиспользования настроек можно создать набор параметров (Property Set).

Создание набора параметров:

  1. Откройте сниппет pdoPage в менеджере;
  2. Перейдите на вкладку «Параметры»;
  3. Нажмите «Добавить набор параметров»;
  4. Назовите например my_pagination;
  5. Заполните нужные параметры;
  6. Сохраните.

Использование набора параметров при вызове:

[[!pdoPage@my_pagination? &parents=`5` &tpl=`itemTpl`]]

Вы можете импортировать готовые наборы параметров из JSON файлов через кнопку «Импорт параметров».

Кастомизация внешнего вида

Пример полной настройки пагинации в стиле Bootstrap 5:

[[!pdoPage?
&limit=`12`
&includeTVs=`image`
&tvPrefix=``
&tpl=`itemTpl`
&tplPageWrapper=`@INLINE <nav aria-label="pagination"> <ul class="pagination">[[+first]][[+prev]][[+pages]][[+next]][[+last]]</ul> </nav>`
&tplPage=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">[[+pageNo]]</a></li>`
&tplPageActive=`@INLINE <li class="page-item active"><span class="page-link">[[+pageNo]]</span></li>`
&tplPageFirst=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">Первая</a></li>`
&tplPageLast=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">Последняя</a></li>`
&tplPagePrev=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">&laquo;</a></li>`
&tplPageNext=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">&raquo;</a></li>`
&tplPageSkip=`@INLINE <li class="page-item disabled"><span class="page-link">...</span></li>`
]]

В шаблонах навигации доступны следующие плейсхолдеры:

  • [[+href]] — ссылка на страницу
  • [[+pageNo]] — номер страницы
  • [[+page]] — текущая страница
  • [[+pageCount]] — общее количество страниц
  • [[+total]] — общее количество результатов
  • [[+limit]] — количество на странице

В шаблоне обертки &tplPageWrapper доступны:

  • [[+first]] — ссылка на первую страницу
  • [[+prev]] — ссылка на предыдущую
  • [[+pages]] — список всех страниц
  • [[+next]] — ссылка на следующую
  • [[+last]] — ссылка на последнюю

 

Оцените статью
MODX 3
Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.