Skip to content

Таблицы ​

Повторяющаяся структура внутри объекта: слайды в слайдере, характеристики товара, участники команды. Таблица описывается один раз, дальше подключается к блоку полем типа Таблица — и редактор наполняет её строками прямо в форме блока.

PageBlocks → Конструктор → Таблицы.

Конструктор таблицы ​

НастройкаЧто делает
НазваниеКак таблица подписана при выборе. Обязательное
МодельГде лежат строки — см. ниже. Обязательное
ПагинацияРазбивать ли список на страницы. Включена по умолчанию
ПоискСтрока поиска над списком — и та же галочка делает таблицу источником глобального поиска
МодерацияНовые строки ждут проверки — см. Модерация. Галочки нет, пока выключена настройка pageblocks_moderation

Вкладки: Поля, Вкладки, Столбцы, Поиск, Фильтрация, Действия, API.

Разделение стоит понять сразу: поля — то, что редактор заполняет; столбцы — то, что он видит в списке. Это разные наборы, и они не обязаны совпадать. Поле может быть доступно поиску или фильтру, вообще не имея столбца.

Отдельной таблицы в базе не появляется ​

Строки всех таблиц лежат в одной pb_table_data, а значения — JSON-ом в колонке data. Принадлежность задаётся тремя ссылками: model_type / model_id — чей это блок, constructor_id — какая таблица, field_id — какое поле.

Что из этого следует

Завести таблицу ничего не стоит: миграций не нужно, схема не меняется. Обратная сторона — искать по «колонке» такой таблицы придётся через JSON_EXTRACT, обычного индекса по ней нет. Для десятков строк на блок это неважно, для десятков тысяч — повод подумать о своей модели.

Столбцы ​

НастройкаЧто делает
Тип колонкиПоле, группа полей или первое непустое из нескольких
ПолеКакое поле показывать
ЗаголовокПереопределяет подпись поля
ШиринаВ пикселях, до 600. 0 — подобрать автоматически
РендерерКак показывать значение
Значение по умолчаниюЧто выводить, когда пусто
СортировкаРазрешить сортировку по этой колонке

Рендереры: text (длинный текст обрезается), html, image, video, date, boolean, button, color. Колонкам с иконкой и статусом рендерер подставляется сам.

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

Вывод в шаблоне ​

Значение поля-таблицы — это массив строк:

html
<div class="slides">
    {foreach $slides as $slide}
        <div class="slide">
            <h3>{$slide.title}</h3>
            <img loading="lazy"
                 src="{$slide.image.url}"
                 width="{$slide.image.width}"
                 height="{$slide.image.height}"
                 alt="{$slide.image.title}">
        </div>
    {/foreach}
</div>

Необязательное поле проверяем перед выводом:

html
{if $description}
    <p>{$description}</p>
{/if}

В шаблон попадают не все строки

Только опубликованные: дата публикации заполнена и не в будущем, строка не удалена. Порядок — тот, что задан перетаскиванием. Строка, которой «нет на сайте», обычно просто не опубликована.

Блок с таблицей на странице

Пресеты: раздел без пятнадцати минут кликов ​

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

bash
# сперва план, ничего не пишется
php core/components/pageblocks/vendor/bin/phinx seed:run \
    -c core/components/pageblocks/src/phinx.php -s PresetCatalogSeed

# запись
PB_APPLY=1 php … -s PresetCatalogSeed

План перечисляет, что именно будет создано; запись включает PB_APPLY=1. Второй прогон не создаёт ничего — всё сперва ищется по имени. После записи сид печатает вызов, который остаётся вставить в страницу:

[[!pbList? &model=`PbTableData` &where=`{"constructor_id":50}` &tpl=`pageblocks.card` &sortby=`menuindex` &limit=`12`]]

Вместе с разделом приезжают две демо-строки — чтобы этот вызов сразу выводил товары, а не пустоту. Дальше правится pageblocks.card: это обычный чанк в дереве элементов.

Раздел можно унести целиком, вместе с заведёнными в нём строками:

bash
PB_REMOVE=1 php … -s PresetCatalogSeed              # план
PB_REMOVE=1 PB_APPLY=1 php … -s PresetCatalogSeed   # запись

Свой пресет

Переиспользуемая часть — Boshnik\PageBlocks\Database\Presets\Builder: table(), tab(), field(), menu(), row(), remove(), все идемпотентные и понимающие режим плана. Новый рецепт — сид строк на сто рядом с PresetCatalogSeed, в основном список полей. Пресету не нужны ни своя миграция, ни своя модель: строки лежат в общем pb_table_data под своим constructor_id — ровно так, как работает таблица, собранная в конструкторе руками.

Модель: обычная таблица или ресурс ​

Модель в настройках — это выбор хранилища.

  • PbTableData — то, что описано выше: строка живёт в общем хранилище и существует внутри своего блока.
  • PbResource — строка попадает в pb_resources и получает собственные колонки ресурса: pagetitle, alias, uri, template, content, menuindex, hidemenu и прочие. Такая строка умеет иметь собственный адрес и собственный шаблон.

Второе нужно, когда строка — это по сути страница: карточка товара, статья каталога, объект справочника. Обычные ресурсы MODX при этом остаются на месте — pb_resources живёт своей таблицей и не подменяет site_content.

Список таких строк можно фильтровать и сортировать как полноценный каталог:

Таблица с фильтрами

© PageBlocks 2019-present