Используем свой сниппет в связке с getPage
- 09.10.2012
- MODx, getPage, Инструкции, Трюки, Сниппеты
Если перед вами стоит задача написать компонент для MODX Revolution, выбирающий некие данные из БД и отображающий их, то с большой долей вероятности вам потребуется добавить постраничную навигацию.
Для MODX Revolution существует отличное дополнение getPage с широкими возможностями, которое превосходно справляется с этой задачей. От вас потребуется совсем немного, что бы подружить ваш компонент с getPage и заставить работать их в связке.
Немного о getPage
getPage - это вспомогательный сниппет, который служит для реализации постраничной навигации на сайте и является своеобразной "оберткой" для других сниппетов.
- Установочный пакет в репозитории: http://modx.com/extras/package/getPage
- Официальная документация: http://rtfm.modx.com/display/ADDON/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, например перечень принимаемых параметров, вы можете посмотреть официальную документацию, ссылка на нее приведена в начале статьи.