MODX pdoPage: параметры, примеры вывода ресурсов с разбивкой на страницы (пагинацией)

MODX pdoPage: параметры, примеры вывода ресурсов с разбивкой на страницы MODX Revo

В данном уроке разберем документацию по сниппету pdoPage и разберемся с выводом ресурсов при помощи pdoPage и с разбивкой их на страницы и сделаем свое оформление постраничной навигации (PdoPage + PageNav + Bootstrap 5). Начнем с документации.

Общие параметры pdoPage

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

Название По умолчанию Описание
&plPrefix Префикс для выставляемых плейсхолдеров
&limit 10 Ограничение количества результатов на странице. Число должно быть больше 0, иначе вам не нужен этот сниппет.
&maxLimit 100 Максимально возможный лимит выборки. Перекрывает лимит, указанный пользователем через url.
&offset 0 Пропуск результатов от начала.
&page 1 Номер страницы для вывода. Перекрывается номером, указанным пользователем через url.
&pageVarKey page Имя переменной для поиска номера страницы в url.
&totalVar page.total Имя плейсхолдера для сохранения общего количества результатов.
&pageLimit 5 Количество ссылок на страницы. Если больше или равно 7 — включается продвинутый режим отображения.
&element pdoResources Имя сниппета для запуска.
&pageNavVar page.nav Имя плейсхолдера для вывода пагинации.
&pageCountVar pageCount Имя плейсхолдера для вывода количества страниц.
&pageLinkScheme Шаблон генерации ссылок на страницы. Позволяет реализовать ЧПУ пагинацию. См. ниже.
&tplPage Чанк оформления обычной ссылки на страницу.
&tplPageWrapper Чанк оформления всего блока пагинации, содержит плейсхолдеры страниц.
&tplPageActive Чанк оформления ссылки на текущую страницу.
&tplPageFirst Чанк оформления ссылки на первую страницу.
&tplPageLast Чанк оформления ссылки на последнюю страницу.
&tplPagePrev Чанк оформления ссылки на предыдущую страницу.
&tplPageNext Чанк оформления ссылки на следующую страницу.
&tplPageSkip Чанк оформления пропущенных страниц при продвинутом режиме отображения (&pageLimit >= 7).
&tplPageFirstEmpty Чанк, выводящийся при отсутствии ссылки на первую страницу.
&tplPageLastEmpty Чанк, выводящийся при отсутствии ссылки на последнюю страницу.
&tplPagePrevEmpty Чанк, выводящийся при отсутствии ссылки на предыдущую страницу.
&tplPageNextEmpty Чанк, выводящийся при отсутствии ссылки на следующую страницу.
&cache 0 Кэширование результатов работы сниппета.
&cacheTime 3600 Время актуальности кэша, в секундах.
&cache_user Принудительно устанавливает ID посетителя, по-умолчанию кеширование производится с учетом ID посетителя
&toPlaceholder Если не пусто, сниппет сохранит все данные в плейсхолдер с этим именем, вместо вывода не экран.
ajax Включить поддержку ajax запросов.
ajaxMode Ajax пагинация «из коробки». Доступны 3 режима: «default», «button» и «scroll».
ajaxElemWrapper #pdopage jQuery селектор элемента-обёртки с результатами и пагинацией.
ajaxElemRows #pdopage .rows jQuery селектор элемента с результатами.
ajaxElemPagination #pdopage .pagination jQuery селектор элемента с пагинацией.
ajaxElemLink #pdopage .pagination a jQuery селектор ссылки на страницу.
ajaxElemMore #pdopage .btn-more jQuery селектор кнопки загрузки результатов при ajaxMode = button.
ajaxHistory Сохранять номер страницы в url при работе в режиме ajax.
frontend_js [[+assetsUrl]]js/pdopage.min.js Ссылка на javascript для подключения сниппетом.
frontend_css [[+assetsUrl]]css/pdopage.min.css Ссылка на css стили оформления для подключения сниппетом.
setMeta 1 Регистрация мета-тегов со ссылками на предыдущую и следующую страницу.
strictMode 1 Строгий режим работы. pdoPage делает редиректы при загрузке несуществующих страниц.

Параметры оформления пагинации (page.nav)

Шаблон По умолчанию
&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>

Если ваш шаблон на bootstrap, то с 90% вероятность вы получите пагинацию с более мене нормальным оформлением, такого вида:

вид пагинации по умолчанию в pdopage

Поддержка Ajax

pdoPage может выдавать JSON и прерывать работу движка при соответствии запроса трём характеристикам:

  • У сниппета включен параметр &ajax.
  • Запрос сделан при помощи XMLHttpRequest, то есть — ajax.
  • В запросе содержится переменная, указанная у сниппета в &pageVarKey. По умолчанию, это page.

Достаточно просто указать сниппету &ajax=`1` и отправить странице GET запрос типа:

$.get('document.html?page=7', function(response) {
    console.log(response);
}, 'json');

И в ответ вы получите JSON c результатами работы, пагинацией и служебными данными: номер страницы, сколько всего страниц и сколько всего результатов. Учитывая, что pdoPage — это сниппет-обёртка, таким образом вы можете заставить работать через ajax многие другие сниппеты.

Встроенная Ajax пагинация

PdoPage умеет загружать страницы через ajax. Вам нужно только обернуть его вызов в специальную разметку:

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

Внутри [[+page.nav]] у нас div с классом pagination — так в pdoPage по умолчанию.

Вы можете менять идентификаторы этой разметки следующими параметрами:

  • ajaxElemWrapper — jQuery селектор элемента-обёртки с результатами и пагинацией. По умолчанию #pdopage.
  • ajaxElemRows — jQuery селектор элемента с результатами. По умолчанию #pdopage .rows
  • ajaxElemPagination — jQuery селектор элемента с пагинацией. По умолчанию #pdopage .pagination
  • ajaxElemLink — jQuery селектор ссылки на страницу. По умолчанию #pdopage .pagination a

Два последних селектора рассчитывают на то, что вы не меняли стандартное оформление блока пагинации в параметре &tplPageWrapper. Работа обеспечивается подключением javascript файла из параметра &frontent_js.

Параметр &ajax=`1` указывать необязательно. Не пустой &ajaxMode активирует его самостоятельно.

Загрузка кнопкой

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

Так что, логично его размещать вверху:

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

Используются всё те же селекторы, плюс:

  • ajaxElemMore — jQuery селектор кнопки загрузки результатов при ajaxMode = button. По умолчанию #pdopage .btn-more.
  • ajaxTplMore — Шаблон кнопки для загрузки новых результатов при ajaxMode = button. Должен включать селектор, указанный в &ajaxElemMore. По умолчанию @INLINE <button class="btn btn-default btn-more">[[%pdopage_more]]</button>

При нажатии на кнопку загружаются &limit элементов и добавляются в конец блока результатов. Если больше загружать нечего — кнопка прячется. Плавающий блок навигации показывает текущую страницу и позволяет быстро перейти куда нужно. Здесь клик уже не обрабатывается через ajax, потому что и так выходит довольно сложно.

Если вывод плавающего блока в пагинацией не нужен, то просто сделайте ему display:none в вашем css.

Загрузка при прокрутке — бесконечная прокрутка страниц

Этот способ очень похож на предыдущий, только нет кнопки и её не нужно нажимать — всё делается автоматически при прокрутке страницы.

<div id="pdopage">
    [[!+page.nav]]
    <div class="rows">
        [[!pdoPage?
            &parents=`0`
            &ajaxMode=`scroll`
        ]]
    </div>
</div>

History API

pdoPage поддерживает работу с History API вашего браузера. Это значит, что когда &ajaxMode включен, сниппет может сохранять номер страницы в адресной строке, чтобы при перезагрузке ничего не терялось. Также правильно работает навигация кнопками «вперёд\назад» браузера.

Вы можете изменить это поведение параметром &ajaxHistory, включив или выключив его. По умолчанию он работает следующим образом:

  • Если ajaxMode установлен в default, то History API используется, номер страницы сохраняется.
  • Если ajaxMode установлен в scroll или button, то History API не используется.

При отключении &ajaxHistory блок в постраничной навигацией скрывается, чтобы страницы нельзя было переключать вручную.

Функции обратного вызова

Вы можете указать функции, которые будут вызываться до и после загрузки страницы через ajax вот так:

pdoPage.callbacks['before'] = function(config) {
    console.log('Конфиг перед загрузкой!', config);
};
pdoPage.callbacks['after'] = function(config, response) {
    console.log('Конфиг после загрузки!', config);
    console.log('Ответ от сервера!', response);
}

Так же есть возможность добавления обработчика на событие pdopage_load:

$(document).on('pdopage_load', function(e, config, response) {
    console.log(e, config, response);
});

Проверка данных в config позволит вам различить разные вызовы pdoPage на одной странице.

Человекопонятная навигация (ЧПУ)

С версии 2.2.2 можно использовать параметр &pageLinkScheme для указания схемы генерации ссылок на страницу. В параметре может быть всего 2 плейсхолдера:

  • [[+pageVarKey]] — переменная с именем страницы. По умолчанию page.
  • [[+page]] — номер страницы

Для примера укажите такой параметр:

[[!pdoPage?
    &parents=`0`
    &pageLinkScheme=`/[[+pageVarKey]]-[[+page]]`
]]
[[!+page.nav]]

Это приведёт к генерации ссылок, типа

/res/news/
/res/news/page-2
/res/news/page-3

При переходе по этим ссылкам (кроме первой) MODX будет выдавать ошибку 404, потому что страниц с этими адресами не существует. Так что, нам нужно написать плагин для их обработки:

<?php
// Реагируем только на событие OnPageNotFound
if ($modx->event->name == 'OnPageNotFound') {
    // Определяем ключ запроса из настроек
    $req = $modx->getOption('request_param_alias');
    // Ловим нужный ключ страницы
    $pageVarKey = 'page';
    // Если в запросе повторяется наш шаблон "pageVarKey-page", то работаем дальше
    if (preg_match("#.*?({$pageVarKey}-(\d+))#", $_REQUEST[$req], $matches)) {
        // Отрезаем ЧПУ строку и получаем точный адрес текущей страницы
        $uri = str_replace($matches[1], '', $matches[0]);

        // Ищем страницу по этому адресу
        $id = 0;
        // Сначала как есть, со слешем на конце
        if (!$id = $modx->findResource($uri)) {
            // Если не находим - то пробуем отрезать слэш и ищем повторно
            $id = $modx->findResource(rtrim($uri, '/'));
        }

        // Если ресурс найден
        if ($id) {
            // Добавляем номер страницы в глобальные массивы, чтобы pdoPage их там увидел
            $_GET[$pageVarKey] = $_REQUEST[$pageVarKey] = $matches[2];
            // И загружаем эту страницу
            $modx->sendForward($id);
        }
        // Если ресурс не был найден - ничего не делаем, возможно запрос поймает другой плагин
    }
}

Теперь этот плагин будет обрабатывать вашу ЧПУ навигацию.

Примеры из оф. документации

Так как pdoPage является частью pdoTools, в параметре &element у него сразу прописан сниппет pdoResources. Поэтому простой вызов сниппета выведет вам дочерние ресурсы:

[[!pdoPage?
    &tpl=`@INLINE <p>[[+idx]] <a href="/[[+uri]]">[[+pagetitle]]</a></p>`
]]
[[!+page.nav]]

Выводим все возможные документы сайта:

[[!pdoPage?
    &tpl=`@INLINE <p>[[+idx]] <a href="/[[+uri]]">[[+pagetitle]]</a></p>`
    &parents=`0`
]]
[[!+page.nav]]

Включаем навигацию с пропуском страниц. Обратите внимание, что если страниц выходит меньше 7, то будет работать обычная навигация.

[[!pdoPage?
    &tpl=`@INLINE <p>[[+idx]] <a href="/[[+uri]]">[[+pagetitle]]</a></p>`
    &parents=`0`
    &pageLimit=`7`
]]
[[!+page.nav]]

Активируем кэш на 30 минут:

[[!pdoPage?
    &tpl=`@INLINE <p>[[+idx]] <a href="/[[+uri]]">[[+pagetitle]]</a></p>`
    &parents=`0`
    &pageLimit=`7`
    &cache=`1`
    &cacheTime=`1800`
]]
[[!+page.nav]]

Указываем максимальный лимит выборки. Теперь, какой бы limit не указал пользователь в url — все равно будет не больше 10 результатов на странице.

[[!pdoPage?
    &tpl=`@INLINE <p>[[+idx]] <a href="/[[+uri]]">[[+pagetitle]]</a></p>`
    &parents=`0`
    &pageLimit=`7`
    &cache=`1`
    &cacheTime=`1800`
    &maxLimit=`10`
]]
[[!+page.nav]]

Источник: docs.modx.pro

Урок на примере реального сайта

Мы с вами начали делать блог и вы его должны били немного наполнить статьями. Теперь нам нужно доработать категорию блога, чтобы выводились статьи и разбивались постранично, к примеру по 10 шт на 1 страницу. Что логично, не выводить же к примеру все 450 статей на одной странице.

Реализуем данный функционал. Для этого откроем чанки (tpl.4) и rowPost созданные в уроке по созданию блога на MODX. И отредактируем их.

В чанке rowPost  у нас сейчас следующее содержимое:

<article class="entry">
    <div class="entry-img">
        <img src="assets/img/blog/blog-1.jpg" alt="MODX pdoPage: параметры, примеры вывода ресурсов с разбивкой на страницы (пагинацией)" class="img-fluid">
    </div>
    <h2 class="entry-title">
        <a href="blog-single.html">Dolorum optio tempore voluptas dignissimos cumque fuga qui quibusdam quia</a>
    </h2>
    <div class="entry-meta">
        <ul>
            <li class="d-flex align-items-center"><i class="bi bi-person"></i> <a href="blog-single.html">John Doe</a></li>
            <li class="d-flex align-items-center"><i class="bi bi-clock"></i> <a href="blog-single.html"><time datetime="2020-01-01">Jan 1, 2020</time></a></li>
            <li class="d-flex align-items-center"><i class="bi bi-chat-dots"></i> <a href="blog-single.html">12 Comments</a></li>
        </ul>
    </div>
    <div class="entry-content">
        <p>Similique neque nam consequuntur ad non maxime aliquam quas. Quibusdam animi praesentium. Aliquam et laboriosam eius aut nostrum quidem aliquid dicta.
           Et eveniet enim. Qui velit est ea dolorem doloremque deleniti aperiam unde soluta. Est cum et quod quos aut ut et sit sunt. Voluptate porro consequatur assumenda perferendis dolore.
        </p>
        <div class="read-more">
            <a href="blog-single.html">Read More</a>
        </div>
    </div>
</article><!-- End blog entry -->

Это статический вывод одной из статей в ленте:

Вывод 1 й из статей в ленте

Сделаем код чанка динамичным (в данном случае для блога на ресурсах):

<article class="entry">
    <div class="entry-img">
        <img src="[[+image]]" alt="[[+pagetitle]]" class="img-fluid">
    </div>
    <h2 class="entry-title">
        <a href="[[+uri]]">[[+pagetitle]]</a>
    </h2>
    <div class="entry-meta">
        <ul>
            <li class="d-flex align-items-center"><i class="bi bi-person"></i> <a href="#">[[+createdby:userinfo=`fullname`]]</a></li>
            <li class="d-flex align-items-center"><i class="bi bi-clock"></i> <time datetime="[[+publishedon:date=`%Y-%m-%dT%H:%M`]]">[[+publishedon:date=`%e %b %Y`]]</time></li>
            <li class="d-flex align-items-center"><i class="bi bi-chat-dots"></i> <a href="[[+uri]]#comments">[[!ticketCommentCount:default=`0`? &id=`[[+id]]`]] коментариев</a></li>
        </ul>
    </div>
    <div class="entry-content">
        <p>[[+introtext]]</p>
        <div class="read-more">
            <a href="[[+uri]]">Подробнее</a>
        </div>
    </div>
</article><!-- End blog entry -->

Здесь вызывается сниппет ticketCommentCount, он достает количество комментариев ресурса и имеет следующий код:

<?php
$q = $modx->newQuery('modResource', $id);
$q->leftJoin('TicketThread','TicketThread', "`TicketThread`.`name` = 'resource-{$id}'");
$q->leftJoin('TicketComment','TicketComment', "`TicketThread`.`id` = `TicketComment`.`thread`");
$q->where(array(
    'TicketComment.published' => 1
));

$q->select('COUNT(`TicketComment`.`id`) as `comments`');

$count = 0;
if ($q->prepare() && $q->stmt->execute()) {
	$count = (integer) $q->stmt->fetch(PDO::FETCH_COLUMN);
}
return $count;

Остальное все стандартное.

Для тех кто использует «Расдел с тикетам» и и внутри статьи на «тикетах» у вас код будет примерно таким:

<article class="entry" id="comment-[[+id]]" data-id="[[+id]]">
    <div class="entry-img">
        <img src="[[+image]]" alt="[[+pagetitle]]" class="img-fluid">
    </div>
    <h2 class="entry-title">
        <a href="[[+uri]]">[[+pagetitle]]</a>
    </h2>
    <div class="entry-meta">
        <ul>
            <li class="d-flex align-items-center"><i class="bi bi-person"></i> <a href="#">[[+fullname]]</a></li>
            <li class="d-flex align-items-center"><i class="bi bi-clock"></i> <time datetime="[[+publishedon:date=`%Y-%m-%dT%H:%M`]]">[[+publishedon:date=`%e %b %Y`]]</time></li>
            <li class="d-flex align-items-center"><i class="bi bi-chat-dots"></i> <a href="[[+uri]]#comments">[[+comments]] коментариев</a></li>
        </ul>
    </div>
    <div class="entry-content">
        <p>[[+introtext]]</p>
        <div class="read-more">
            <a href="[[+uri]]">Подробнее</a>
        </div>
    </div>
</article><!-- End blog entry -->

Теперь выведем статьи при помощи pdoPage (заменяем вызов чанка rowPost на вызов ниже):

[[!pdoPage?
  &limit=`2`
  &includeTVs=`image`
  &tvPrefix=``
  &tpl=`rowPost`
  &where = `hidemenu=1`
]]

Здесь я указал limit вывода 2, т.к. у меня пока всего 3 поста, чтобы увидеть пагинацию и условие &where = `hidemenu=1` чтобы отображались только ресурсы скрытые в меню (это в моем случае статьи, категории не скрываю). Т.е. получается универсальный вывод для главной категории блоги и его подкатегорий. Т.к. шаблон на bootstrap если мы вызовем [[!+page.nav]], то получим довольно адекватный вид пагинации.

Пример стандартной пагинации

Давайте подгоним пагинацию под шаблон, ее статически код следующий:

<div class="blog-pagination">
    <ul class="justify-content-center">
        <li><a href="#">1</a></li>
        <li class="active"><a href="#">2</a></li>
        <li><a href="#">3</a></li>
    </ul>
</div>

Перенесем его в вызов pdoPage и получим следующее:

[[!pdoPage? 
    &limit=`1`
    &includeTVs=`image`
    &tvPrefix=`` 
    &tpl=`rowPost` 
    &where=`hidemenu=1`
    &tplPageWrapper=`@INLINE <div class="blog-pagination"><ul class="justify-content-center">[[+prev]][[+pages]][[+next]]</ul></div>`
    &tplPageFirst=``
    &tplPageLast=``
    &tplPage=`@INLINE <li><a href="[[+href]]">[[+pageNo]]</a></li>`
    &tplPageActive=`@INLINE <li class="active"><a href="[[+href]]">[[+pageNo]]</a></li>`
    &tplPagePrev=``
    &tplPageNext=``
    &tplPagePrevEmpty=``
    &tplPageNextEmpty=``
    &tplPageFirstEmpty=``
    &tplPageLastEmpty=``
]]
[[!+page.nav]]

Здесь мы грубо говоря заменили стандартные параметры оформления пагинации (page.nav).

Новая пагинация

Важно! Если у вас секции тикетса и сами тикеты, то в вызов выше вам нужно добавить следующие параметры:

&element=`getTickets`
&prepareTVs=`img`
&where = `hidemenu=1` - думаю можно удалить

Кто делает блог по моим урокам, у вас содержимое чанка tpl.4 должно стать таким (для блога на ресурсах):

<div class="container py-4">
	<div class="row">
               [[$sidebar]]
		<div class="col-lg-9 order-lg-1">
			<div class="blog-posts">
				<div class="row px-3"> 
                    [[!pdoPage?
                        &limit=`2`
                        &includeTVs=`img`
                        &tvPrefix=``
                        &tpl=`rowPost`
                        &tplPageWrapper=`@INLINE <ul class="pagination float-end">[[+prev]][[+pages]][[+next]]</ul>`
                        &tplPageFirst=``
                        &tplPageLast=``
                        &tplPage=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]">[[+pageNo]]</a></li>`
                        &tplPageActive=`@INLINE <li class="page-item active"><a class="page-link" href="[[+href]]">[[+pageNo]]</a></li>`
                        &tplPagePrev=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]"><i class="fas fa-angle-left"></i></a></li>`
                        &tplPageNext=`@INLINE <li class="page-item"><a class="page-link" href="[[+href]]"><i class="fas fa-angle-right"></i></a></li>`
                        &tplPagePrevEmpty=`@INLINE <li class="page-item disabled"><a class="page-link" href="[[+href]]"><i class="fas fa-angle-left"></i></a></li>`
                        &tplPageNextEmpty=`@INLINE <li class="page-item disabled"><a class="page-link" href="[[+href]]"><i class="fas fa-angle-right"></i></a></li>`
                        &tplPageFirstEmpty=``
                        &tplPageLastEmpty=``
                        &where = `hidemenu=1`
                    ]]
				</div>
				<div class="row">
					<div class="col">
					    [[!+page.nav]]
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

Для тех кто пишет делает все на на феноме, вот вам пример выводов:

<div class="container py-4">
	<div class="row">
        {include 'sidebar'}
		<div class="col-lg-9 order-lg-1">
			<div class="blog-posts">
				<div class="row px-3"> 
                    {'!pdoPage' | snippet : [
                        'limit' => '2',
                        'includeTVs' => 'img',
                        'tvPrefix' => '',
                        'tpl' => 'rowPost',
                        'tplPageWrapper' => '@INLINE <ul class="pagination float-end">{$prev}{$pages}{$next}</ul>',
                        'tplPageFirst' => '',
                        'tplPageLast' => '',
                        'tplPage' => '@INLINE <li class="page-item"><a class="page-link" href="{$href}">{$pageNo}</a></li>',
                        'tplPageActive' => '@INLINE <li class="page-item active"><a class="page-link" href="{$href}">{$pageNo}</a></li>',
                        'tplPagePrev' => '@INLINE <li class="page-item"><a class="page-link" href="{$href}"><i class="fas fa-angle-left"></i></a></li>',
                        'tplPageNext' => '@INLINE <li class="page-item"><a class="page-link" href="{$href}"><i class="fas fa-angle-right"></i></a></li>',
                        'tplPagePrevEmpty' => '@INLINE <li class="page-item disabled"><a class="page-link" href="{$href}"><i class="fas fa-angle-left"></i></a></li>',
                        'tplPageNextEmpty' => '@INLINE <li class="page-item disabled"><a class="page-link" href="{$href}"><i class="fas fa-angle-right"></i></a></li>',
                        'tplPageFirstEmpty' => '',
                        'tplPageLastEmpty' => '',
                        'where' => ['hidemenu' => 1],
                    ]}
				</div>
				<div class="row">
					<div class="col">
					    {'page.nav' | placeholder}
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

Чанк rowPost:

<div class="col-sm-6">
	<article class="post post-medium border-0 pb-0 mb-5">
		<div class="post-image">
            <a href="{$uri}">
            	<img src="{$img}" class="img-fluid img-thumbnail img-thumbnail-no-borders rounded-0" alt="{$pagetitle}">
            </a>
		</div>
		<div class="post-content">
        <h2 class="font-weight-semibold text-5 line-height-6 mt-3 mb-2"><a href="{$uri}">{$pagetitle}</a></h2>
            <p>{$introtext}</p>
            <div class="post-meta" data-id="{$id}">
            	<span><i class="far fa-user"></i> Опубликовал <a href="#">{$createdby | user : 'fullname'}</a> </span>
            	<span><i class="far fa-folder"></i> <a href="{$parent | url}">{$parent | resource : 'pagetitle'} </a> </span>
            	<span><i class="far fa-comments"></i> <a href="{$uri}#comments">{'!ticketCommentCount' | snippet : [ 'id' => $id, ]} </a></span>
            	<span class="d-block mt-2"><a href="{$uri}" class="btn btn-xs btn-light text-1 text-uppercase">Читать полностью</a></span>
            </div>

		</div>
	</article>
</div>

C первого взгляда выглядит довольно громоздко и сложно, но это не так. Посмотрите видео как это все делается и вам станет все понятнее.

А если остались вопросы, задавайте в комментариях. В следующем уроке разберем еще один сниппет от PdoTools: pdoNeighbors — выводит соседние ресурсы.

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 6 оценок, среднее 2.83 из 5 )
Web-Revenue.ru
Добавить комментарий

  1. Иван

    Возможно ли сделать одновременно разбивку по страницам и загрузку по кнопке?

    Ответить
    1. Алексей автор

      Я такого не делал, но чисто теоретически думаю можно (как минимум нужно править родной JS файл, может еще что-то).

      Ответить
  2. Юрий

    Здравствуйте, хотелось бы увидеть пример на Fenom, с максимальным вызовом функций (например includeTVs, tplPageActive)

    Ответить
    1. Алексей автор

      Здравствуйте. Сделал — смотрите в конце статьи.

      Ответить