Используем свой сниппет в связке с getPage

Если перед вами стоит задача написать компонент для MODX Revolution, выбирающий некие данные из БД и отображающий их, то с большой долей вероятности вам потребуется добавить постраничную навигацию.

Для MODX Revolution существует отличное дополнение getPage с широкими возможностями, которое превосходно справляется с этой задачей. От вас потребуется совсем немного, что бы подружить ваш компонент с getPage и заставить работать их в связке.

Немного о getPage

getPage - это вспомогательный сниппет, который служит для реализации постраничной навигации на сайте и является своеобразной "оберткой" для других сниппетов.

Как работает getPage?

Допустим у вас есть сниппет mySnippet, который выводит некий результат построчно. Обычно вы так вызываете этот сниппет, передавая ему какие-то параметры:

[[mySnippet? &x=`1` &y=`2`]]

Но вот проблема, mySnippet раньше выводил 6 строчек с результатом, а теперь вы добавили новые материалы на сайт и он выводит  несколько десятков строк на одной странице, что очень неудобно. Необходимо добавить постраничную навигацию.

В этом случае и пригодится getPage. Вам потребуется немного модифицировать mySnippet, чтобы обеспечить корректное взаимодействие с getPage. При этом код вызова mySnippet изменится, он станет обернут в getPage, а параметры вы будете передавать в getPage, а он, в свою очередь, передаст их в mySnippet:

[[!getPage?               #вызов getPage всегда НЕКЕШИРУЕМЫЙ
 &limit=`15`              #количество элементов на странице
 &element=`mySnippet`     #ваш сниппет mySnippet
 &x=`1`                   #параметры mySnippet
 &y=`2`
]]

[[!+page.nav]] #getPage устанавливает этот плейсхолдер, он содержит блок ссылок с номерами страниц

Для работоспособности этого кода требуется, чтобы ваш сниппет правильно обрабатывал несколько переменных, таких как limit, offset, total, totalVar. Через эти переменные getPage "разговаривает" с вашим сниппетом, передавая и получая информацию об общем количестве строк и текущей странице.

Узнаем общее количество строк

Прежде всего, ваш сниппет должен сообщить getPage общее количество строк с данными, что бы getPage смог правильно рассчитать количество страниц.

Сразу пример кода, который необходимо добавить в mySnippet:

$q = $modx->newQuery("modResource");
$q->where('published'=>1, 'template'=>1);
$total=$modx->getCount("modResource", $q);
$totalVar=$modx->getOption('totalVar', $scriptProperties, 'total');
$modx->setPlaceholder($totalVar,$total);

 Разберем этот код построчно.

  • Строки 1-2. Создаем запрос в базу данных через xPDO, в данном примере к объекту modResource и задаем критерии выборки.
  • Строка 3. Получаем количество записей, удовлетворяющих критерию. Обратите внимание, что мы используем getCount, а не getCollection и затем count. getCount не извлекает данные из БД, а просто получает количество строк и поэтому работает максимально быстро.
  • Строка 4. Если посмотреть документацию getPage, то можно увидеть? что в totalVar хранится ключ плейсхолдера, отвечающего за общее количество строк. Здесь мы получаем этот ключ. По умолчанию это "total".
  • Строка 5. А теперь мы устанавливаем значение плейсхолдера с ключем totalVar в $total. Именно это значение и будет использовать getPage.

Таким образом мы видим, что для задания общего количества строк в вашем сниппете необходимо установить плейсхолдер с ключем totalVar.

Выбираем данные

Отлично, getPage знает, сколько всего страниц будет. А как узнать в нашем сниппете о том, какая сейчас страница, и соответственно, какие данные отобразить? Для этой цели служат параметры limit и offset, их уже передает getPage нашему сниппету. Все, что остается, это их получить и использовать. Расширим предыдущий пример кода:

$q = $modx->newQuery("modResource");
$q->where('published'=>1, 'template'=>1);
$total=$modx->getCount("modResource", $q);
$totalVar=$modx->getOption('totalVar', $scriptProperties, 'total');
$modx->setPlaceholder($totalVar,$total);
$limit=$modx->getOption('limit', $scriptProperties, 10);
$offset=$modx->getOption('offset', $scriptProperties, 0);
$q->limit($limit, $offset);
$data=$modx->getCollection('modResource',$q)

Рассмотрим новый код построчно:

  • Строки 6 и 7. Получаем значения переменных limit и offset. Первая определяет количество элементов на странице, а вторая - смещение выбираемых данных от начала.
  • Строка 8. Задаем предел выборки в нашем запросе к БД.
  • Строка 9. Запрашиваем нужные данные. Теперь можем их вывести.

Все просто

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

Использовать getPage для постраничной навигации - это верное решение, которое позволяет вести быструю разработку и в дальнейшем без проблем осуществлять поддержку и развитие сайта.

Если вам необходима более подробная информация по getPage, например перечень принимаемых  параметров, вы можете посмотреть официальную документацию, ссылка на нее приведена в начале статьи.