pdoResources — документация и примеры вывода ресурсов

modx pdoResources - документация и примеры вывода ресурсов MODX Revo

Приветствую вас уважаемые читатели! В предыдущих статьях мы наполнили сайт контентом, сделали меню и хлебные крошки. Сегодня мы изучим сниппет pdoResources, который входит в состав пакета PdoTools и предназначен для вывода ресурсов в любом оформлении на любой странице.

Документация по pdoResources

Параметры выборки ресурсов

Эти параметры определяют, какие ресурсы появятся в генерируемом списке.

Название По умолчанию Описание
&parents Текущий ресурс Список родителей, через запятую, для поиска результатов. Если поставить 0 — выборка не ограничивается. Если id родителя начинается с дефиса, он и его потомки исключаются из выборки.
&depth 10 Глубина поиска дочерних ресурсов от родителя.
&resources Список ресурсов, через запятую, для вывода в результатах. Если id ресурса начинается с дефиса, этот ресурс исключается из выборки.
&context Ограничение выборки по контексту ресурсов.
&where Массив дополнительных параметров выборки, закодированный в JSON.
&showHidden 1 Показывать ресурсы, скрытые в меню.
&showUnpublished 0 Показывать неопубликованные ресурсы.
&showDeleted 0 Показывать удалённые ресурсы.
&hideContainers 0 Отключает вывод контейнеров, то есть, ресурсов с «isfolder = 1».
&select 0 Список полей для выборки, через запятую. Можно указывать JSON строку с массивом, например {«modResource»:»id,pagetitle,content»}.
&sortby pagetitle Любое поле ресурса для сортировки, включая ТВ параметр, если он указан в параметре &includeTVs. Можно указывать JSON строку с массивом нескольких полей, например {«tvname»:»ASC», «pagetitle»:»DESC»}. Для случайно сортировки укажите «RAND()»
&sortdir DESC Направление сортировки: по убыванию или возрастанию.
&setTotal 0 Отключение выборки total по умолчанию (с версии 2.11.0). Сниппет pdoPage включает его всегда.
&limit 10 Ограничение количества результатов выборки. Можно использовать «0».
&offset 0 Пропуск результатов от начала. Необходимо использовать вместе с явно указанным &limit
&first 1 Номер первой итерации вывода результатов.
&last Автоматически, по формуле (total + first — 1) Номер последней итерации вывода результатов.
&loadModels Список компонентов, через запятую, чьи модели нужно загрузить для построения запроса. Например: &loadModels=`ms2gallery,msearch2`.
&tvFilters Список фильтров по ТВ, с разделителями AND и OR. Разделитель, указанный в параметре &tvFiltersOrDelimiter представляет логическое условие OR и по нему условия группируются в первую очередь. Внутри каждой группы вы можете задать список значений, разделив их &tvFiltersAndDelimiter. Поиск значений может проводиться в каком-то конкретном ТВ, если он указан «myTV==value», или в любом «value». Пример вызова: &tvFilters=`filter2==one,filter1==bar%||filter1==foo`. Обратите внимание: фильтрация использует оператор LIKE и знак «%» является метасимволом. И еще: Поиск идёт по значениям, которые физически находятся в БД, то есть, сюда не подставляются значения по умолчанию из настроек ТВ.
&tvFiltersAndDelimiter «,» Разделитель для условий AND в параметре &tvFilters.
&tvFiltersOrDelimiter «||» Разделитель для условий OR в параметре &tvFilters.

Параметры шаблонов

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

Название Описание
&returnIds Установите значение «1», чтобы вернуть строку со списком id ресурсов, вместо оформленных результатов. Все указанные шаблоны игнорируются.
&tpl Имя чанка для оформления ресурса. Если не указан, то содержимое полей ресурса будет распечатано на экран.
&tplFirst Имя чанка для первого ресурса в результатах.
&tplLast Имя чанка для последнего ресурса в результатах.
&tplOdd Имя чанка для каждого второго ресурса (хоть «odd» значит «нечётный», работает для чётных ресурсов).
&tplWrapper Чанк-обёртка, для заворачивания всех результатов. Понимает один плейсхолдер: [[+output]]. Не работает вместе с параметром &toSeparatePlaceholders.
&wrapIfEmpty Включает вывод чанка-обертки &tplWrapper даже если результатов нет.
&tplCondition Поле ресурса, из которого будет получено значение для выбора чанка по условию в &conditionalTpls.
&tplOperator Необязательный оператор для проведения сравнения поля ресурса в &tplCondition с массивом значений и чанков в &conditionalTpls.
&conditionalTpls JSON строка с массивом, у которого в ключах указано то, с чем будет сравниваться &tplCondition, а в значениях — чанки, которые будут использованы для вывода, если сравнение будет успешно. Оператор сравнения указывается в &tplOperator. Для операторов типа isempty можно использовать массив без ключей.
&outputSeparator Необязательная строка для разделения результатов работы.

Параметры результатов

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

Название По умолчанию Описание
&fastMode 0 Быстрый режим обработки чанков. Все необработанные теги (условия, сниппеты и т.п.) будут вырезаны.
&idx Вы можете указать стартовый номер итерации вывода результатов.
&totalVar total Имя плейсхолдера для сохранения общего количества результатов. Параметр setTotal должен быть включен.
&includeContent 0 Включаем поле «content» в выборку.
&includeTVs Список ТВ параметров для выборки, через запятую. Например: «action,time» дадут плейсхолдеры [[+tv.action]] и [[+tv.time]].
&prepareTVs «1», что означает подготовку всех ТВ, указанных в &includeTVs Список ТВ параметров, которые нужно подготовить перед выводом.
&processTVs Список ТВ параметров, которые нужно обработать перед выводом. Если установить в «1», будут обработаны все ТВ, указанные в &includeTVs.
&tvPrefix tv. Префикс для ТВ параметров.
&useWeblinkUrl Генерировать ссылку с учетом класса ресурса, включает плейсхолдер [[+link]].
&toPlaceholder Если не пусто, сниппет сохранит все данные в плейсхолдер с этим именем, вместо вывода не экран.
&toSeparatePlaceholders Если вы укажете слово в этом параметре, то ВСЕ результаты будут выставлены в разные плейсхолдеры, начинающиеся с этого слова и заканчивающиеся порядковым номером строки, от нуля. Например, указав в параметре «myPl», вы получите плейсхолдеры [[+myPl0]][[+myPl1]] и т.д.
&showLog 0 Показывать дополнительную информацию о работе сниппета. Только для авторизованных в контекте «mgr».

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

Простейший вывод списка дочерних ресурсов документа с идентификатором 1:

[[pdoResources?
    &parents=`1`
    &depth=`0`
    &tpl=`ListRowTpl`
]]

Если используется дополнительное поле image, то вызов изменится следующим образом:

[[pdoResources?
    &parents=`1`
    &depth=`0`
    &tpl=`ListRowTpl`
    &includeTVs=`image`
]]

В чанке ListRowTpl за это поле будет отвечать плейсхолдер [[+tv.image]]

Официальная документация по pdoresources.

Реальный пример вывода ресурсов

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

Статический блок с услугами

А статический код этого блока такой:

<!-- ======= Services Section ======= -->
    <section id="services" class="services">

      <div class="container" data-aos="fade-up">

        <header class="section-header">
          <h2>Services</h2>
          <p>Veritatis et dolores facere numquam et praesentium</p>
        </header>

        <div class="row gy-4">

          <div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="200">
            <div class="service-box blue">
              <i class="ri-discuss-line icon"></i>
              <h3>Nesciunt Mete</h3>
              <p>Provident nihil minus qui consequatur non omnis maiores. Eos accusantium minus dolores iure perferendis tempore et consequatur.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

          <div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="300">
            <div class="service-box orange">
              <i class="ri-discuss-line icon"></i>
              <h3>Eosle Commodi</h3>
              <p>Ut autem aut autem non a. Sint sint sit facilis nam iusto sint. Libero corrupti neque eum hic non ut nesciunt dolorem.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

          <div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="400">
            <div class="service-box green">
              <i class="ri-discuss-line icon"></i>
              <h3>Ledo Markt</h3>
              <p>Ut excepturi voluptatem nisi sed. Quidem fuga consequatur. Minus ea aut. Vel qui id voluptas adipisci eos earum corrupti.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

          <div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="500">
            <div class="service-box red">
              <i class="ri-discuss-line icon"></i>
              <h3>Asperiores Commodi</h3>
              <p>Non et temporibus minus omnis sed dolor esse consequatur. Cupiditate sed error ea fuga sit provident adipisci neque.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

          <div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="600">
            <div class="service-box purple">
              <i class="ri-discuss-line icon"></i>
              <h3>Velit Doloremque.</h3>
              <p>Cumque et suscipit saepe. Est maiores autem enim facilis ut aut ipsam corporis aut. Sed animi at autem alias eius labore.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

          <div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="700">
            <div class="service-box pink">
              <i class="ri-discuss-line icon"></i>
              <h3>Dolori Architecto</h3>
              <p>Hic molestias ea quibusdam eos. Fugiat enim doloremque aut neque non et debitis iure. Corrupti recusandae ducimus enim.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

        </div>

      </div>

    </section><!-- End Services Section -->

Первым делом создаем чанк где будет формироваться оформление и контент, назовем его TplServices и вставим в него повторяющуюся часть кода (одну из плиток):

<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="200">
            <div class="service-box blue">
              <i class="ri-discuss-line icon"></i>
              <h3>Nesciunt Mete</h3>
              <p>Provident nihil minus qui consequatur non omnis maiores. Eos accusantium minus dolores iure perferendis tempore et consequatur.</p>
              <a href="#" class="read-more"><span>Read More</span> <i class="bi bi-arrow-right"></i></a>
            </div>
          </div>

Теперь разметим данный блок синтаксисом и русифицируем:

<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="[[+idx]]00">
    <div class="service-box [[+idx:colorBox]]">
        <i class="ri-discuss-line icon"></i>
        <h3>[[+pagetitle]]</h3>
        <p>[[+content:strip_tags:ellipsis=`70`]]</p>
        <a href="[[+uri]]" class="read-more"><span>Подробнее</span> <i class="bi bi-arrow-right"></i></a>
    </div>
</div>
fenom

<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="{$idx}00">
    <div class="service-box {$idx | colorBox}">
        <i class="ri-discuss-line icon"></i>
        <h3>{$pagetitle}</h3>
        <p>{$content | notags | truncate : 70 : ' ... ' : true : true}</p>
        <a href="{$uri}" class="read-more"><span>Подробнее</span> <i class="bi bi-arrow-right"></i></a>
    </div>
</div>

И сохраним чанк.

Краткий разбор:

  • [[+idx]] — номер итерации вывода результатов (1, 2, 3, …6);
  • [[+uri]] — формирует ссылку на ресурс;
  • [[+pagetitle]] — заголовок ресурса;
  • [[+content]] — выводит текстовую часть;
  • strip_tags и ellipsis — модификаторы: удаляет html разметку и обрезает текст;
  • colorBox — самодельный сниппет — модификатор, со следующим содержимым:
    <?php
    $color_arr = array(
        '1' => 'blue',
        '2' => 'orange',
        '3' => 'green',
        '4' => 'red',
        '5' => 'purple',
        '6' => 'pink',
    );
    $idx = $input;
    $color = $idx;
    $color = $color_arr[$color];
    return "$color";

Можно было бы обойтись без создания сниппета, наколхозить что-то типа такого:

[[+idx:is=`1` :then=`blue`]][[+idx:is=`2` :then=`orange`]]...[[+idx:is=`6` :then=`pink`]]

Теперь в месте где нужно вывести данное содержимое вызываем его при помощи pdoResources.

[[pdoResources?
    &parents=`7`
    &limit=`6`
    &includeContent=`1`
    &tpl=`TplServices`
]]
fenom

{'pdoResources' | snippet : [
    'parents' => '7',
    'limit' => '6',
    'includeContent' => '1',
    'tpl' => 'TplServices'
]}

Краткое описание параметров:

  • &parents=`7` — id родителя ресурсов, от куда брать контент (0 — все ресурсы);
  • &limit=`6`— максимальное количество результатов для вывода;
  • &includeContent=`1` — включаем в выборку content (область с текстовым редактором);
  • &tpl=`TplServices` — чанк оформления, для вывода ресурсов;

Таким образом можно вывести практически все что угодно.

Вывод ресурсов при помощи fenom.

И так в курсе по Fenom мы создали блог и добавили в него статьи, теперь выведем последние 3 статьи на главной странице сайта, для этого откроем наш шаблон HomeTemplate.tpl и в место надписи «Здесь будет выборка статей» помещаем вызов:

<div class="row">
    {'!pdoResources' | snippet : [
        'parents' => '10',
        'limit' => '3',
        'depth' => '0',
        'tpl' => '@FILE chunks/home/resourcesBlog.tpl',
        'includeTVs' => 'img',
        'tvPrefix' => '',
        'sortdir' => 'ASC'
    ]}
</div>

где chunks/home/resourcesBlog.tpl чанк с именем resourcesBlog.tpl созданный в директории chunks/home/. Кто работает не на файлах у вас просто «имя чанка». А в чанке следующий код:

<div class="col-sm-4">
    <div class="card h-100">
        <a href="{$uri}"><img class="card-img-top" src="{$img | pthumb : 'w=354&h=156&zc=1'}" alt="{$pagetitle}"></a>
        <div class="card-body">
            <h3 class="h6 card-title"><a class="link-dark" href="{$uri}">{$pagetitle}</a></h3>
            <div class="card-text small">{$introtext | truncate : 100 : ' ... ':true:true}</div>
        </div>
    </div>
</div>

Получаем:

Блок с тремя последними новостями

2 вывода на одной странице, чтобы не дублировались ресурсы.

Задача: Есть новостной сайт там на главной странице сделано несколько вызовов ресурсов при помощи pdoResources. В верху выводятся ресурсы (4 штуки) у которых в TV «editorSelected» выбрано значение «4news». Имеет вызов:

[[!pdoResources?
    &parents=`7,9,12,11,10`
    &level=`2`
    &limit=`4`
    &hideContainers=`1`
    &includeTVs=`imgNews,editorSelected`
    &where=`{"editorSelected":"4news"}`
    &sortby=`{"publishedon":"DESC"}`
    &tpl=`tplNewsMain04`
]]

А ниже выводятся 10 последних новостей. И нужно чтобы в 10 последних новостях, вывод следующий.

[[pdoResources?
    &parents=`7,9,10,12,11`
    &level=`2`
    &limit=`8`
    &includeTVs=`editorSelected,imgNews`
    &sortby=`publishedon`
    &sortdir=`DESC`
    &tpl=`tplNewsMain2`
    &hideContainers=`1`
]]

И часто в этот блок попадают новости из верхнего, нужно чтобы не выводились одинаковые ресурсы.

Решение.

Самое простое это исключить из выборки «4news»: &where=`{«editorSelected:NOT LIKE»:»4news»}`. Но редакторы каждый 2й ресурс помечают этим условие, следовательно ниже исключится примерно 5 свежих ресурсов — что тоже не хорошо. Поэтому решение 2.

Создаем сниппет «runn» со следующим содержимым.

<?php
$ids = $modx->runSnippet('pdoResources', array(
    'parents'=>'7,9,12,11,10',
    'level'=>'2',
    'limit'=>'4',
    'hideContainers'=>'1',
    'includeTVs'=>'imgNews,editorSelected',
    'where'=>'{ "editorSelected":"4news" }',
    'sortby'=>'{ "publishedon":"DESC" }',
    'returnIds'=>1
));
$noids = '-'.str_replace(',', ',-', $ids);
$modx->setPlaceholders(array(
    'rids'=>$ids,
    'norids'=>$noids
));
return;

Здесь rids собирает id выведенных ресурсов, а norids получается выводит id ресурсов через «-«.

Далее вызываем сниппет перед первым вызовом где 4 новости «[[runn]]».

А во второй вызов добавляем &resources=`[[+norids]]`.

[[pdoResources?
    &parents=`7,9,10,12,11`
    &level=`2`
    &limit=`8`
    &includeTVs=`editorSelected,imgNews`
    &sortby=`publishedon`
    &sortdir=`DESC`
    &tpl=`tplNewsMain2`
    &hideContainers=`1`
    &resources=`[[+norids]]`
]]

pdoResources в pdoResources

Иногда в чанке одного вызова pdoResources нужно вывести другой. Рассмотрим на примере. Я сейчас делаю сайт с документацией по bootstrap, структура у сайта вот такая:

Структура документации

В главной ветке (с id 2), хочу вывести названия подразделов (id 4,5,6,… и их introtext, а под ними ограниченный список ресурсов (к примеру первые 5 из каждой ветки) и ссылку смотреть все — которая ведет на эту ветку. В общем получился вот такой вызов:

<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
[[!pdoResources?
    &parents=`3`
    &depth=`0`
    &tpl=`allDoc`
    &sortby=`menuindex`
    &sortdir=`ASC`
]]
</div>

Где чанк allDoc имеет следующее содержимое:

<div class="col">
    <div class="card text-center mt-3">
      <div class="card-header">
        <h2 class="card-title">[[+pagetitle]]</h2>
      </div>
      <div class="card-body">
        <p class="card-text">[[+introtext]]</p>
        <hr>
    	<ul class="list-group list-group-flush">
    	[[!pdoResources?
    		&parents=`[[+id]]`
    		&depth=`0`
    		&limit=`5`
    		&tpl=`allDocListGroups`
    		&sortby=`menuindex`
    		&sortdir=`ASC`
    	]]
    	</ul>
      </div>
      <div class="card-footer">
        <a class="text-muted" href="[[+uri]]">смотреть все</a>
      </div>
    </div>
</div>

Как вы видите в данном чанке снова вызывается pdoResources с немного другими параметрами и со следующим содержимым чанка allDocListGroups:

<li class="list-group-item"><a href="[[+uri]]">[[+pagetitle]]</a></li>

В конечном итоге получилось следующее:

Получившийся блок

Таким же образом в чанк можно помещать вызовы и других сниппетов к примеру вызов товаров minishop2:

[[!msProducts? &parents=`[[+id]]` ....]]

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

[[!pdoResources? &where=`{"class_key":msCategory}` returnIds=`1` ....]]

Как ничего не выводить, если ресурсов нет?

Часто мы делаем различные выборки ресурсов, например автоматическая перелинковка:

авто перелинковка

Если перелиновывать будет не с чем, то у нас в коде (во фронт энд) все равно останется обвертка:

<h4>Похожие статьи:</h4>
<div class="row">

</div>

Вот чтобы, если результатов нет, используйте параметры: tplWrapper (чанк-обёртка, для заворачивания всех результатов) и wrapIfEmpty (включает вывод чанка-обертки &tplWrapper), смотрите выше параметры. Иными словами выносим нашу обвертку в отдельный чанк, назовем его myWrapper:

<h4>Похожие статьи:</h4> 
<div class="row">
[[+output]]
</div>

А дальше все также сделаем наш вызов только с 2 выше указанными параметрами:

[[pdoResources?
    &parents=`[[*parent]]`
    &resources=`-[[*id]]`
    &includeTVs=`img`
    &depth=`0`
    &limit=`4`
    &tpl=`relation`
    &sortdir=`ASC`
    &tplWrapper=`myWrapper` 
    &wrapIfEmpty=`0`
]]

Все если нет результатов, то и в коде не чего нет)

В следующих уроках разберем как сделать блог, наполним его и можно изучить следующий компонент из пакета PdoTools: pdoPage (почти тоже самое но с разбивкой на страницы — с пагинацией).

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

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

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

  1. Юлия Бекенёва

    подскажите пожалуйста, как вывести дату? в вызове pdoResources что прописывать?

    Ответить
    1. Голягин Алексей

      на стандартном шаблонизаторе на пример так: [[+publishedon:strtotime:date=`%e %B %Y`]]
      на fenom {$publishedon | date : «d/m/Y»}
      Смотрите статью: https://web-revenue.ru/modx-revo/formatirovanie-dat-i-vremeni

      Ответить
      1. Юлия Бекенёва

        Спасибо! Получилось еще до вашего ответа)))

        Ответить
  2. Андрей

    Прошу помочь. Я вывел картинку ресурса, но она вывелась с двумя слешами в начале (//assets/image.jpg). Как их убрать или что дописать?

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

      Допишите в вывод &scheme=`full`, если не поможет напишите какой путь вывелся

      Ответить
  3. Михаил

    Здравствуйте! ПАМАГИТЕ
    Должны быть категории на странице в виде картинки и снизу название категории, таких на странице должно быть много. А при нажатии на такую категорию, должны появиться товары в таком же виде(карточка товара не нужна). Уже сломал голову.
    Категории вывести получилось, но на этой же странице отображаются и товары все, а если их как-то убрать, то они исчезают и внутри категорий. как их убрать со страницы с категориями, но при этом оставить внутри категории?

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

      Здравствуйте.

      &depth =`1` &parents=`[[*parent]]`
      Ответить