Хотите собрать главную страницу сайта или лендинг на MODX, не дублируя десятки чанков и не создавая бесконечные TV-поля? Знакомьтесь с PageBlocks (Free версия). Это идеальный «конструктор блоков», который превращает админку MODX в подобие Tilda или Elementor, но с полным контролем над кодом.
В этой статье разберем, как бесплатно и быстро развернуть удобный конструктор, который работает на MODX 3.x, PHP 8.2+ и летает благодаря Fenom.
- Что такое PageBlocks Free и почему он лучше MIGX
- Установка и базовая настройка
- Типы полей для блоков и таблиц (ваш арсенал)
- Таблица всех 23 типов полей + как их выводить
- Обзор интерфейса: как создавать блоки и таблицы
- 1. Создание нового блока (Конфигурация)
- 2. Добавление полей (Visual Builder)
- 3. Настройка сетки и вкладок (опционально)
- 4. Создание таблиц и полей с типом TableList — замена MIGX
- 5. Заполнение контентом (вид из ресурса)
- Практика: интеграция шаблона «Small Business»
- 1. Анализ и «нарезка» шаблона
- 2. Создаем Блок 1: «Приветствие» (Heading Row)
- 3. Создаем Блок 2: «Call to Action»
- 4. Создаем Блок 3: «Карточки услуг» (Content Row)
- 5. Собираем всё в шаблоне страницы
- Дополнительно: сажаем Bootstrap Carrusel (слайдер)
- 2. Чанк pb.carousel с логикой Fenom
- Заключение
Что такое PageBlocks Free и почему он лучше MIGX
PageBlocks — это компонент от Александра Хуза (boshnik), который меняет подход к сборке страниц.
Главные фишки Free-версии:
- Неограниченное количество блоков на странице.
- Drag & Drop: менеджеры могут менять блоки местами простым перетаскиванием.
- Fenom из коробки*: не нужно ставить дополнительные парсеры (*в платной версии, для бесплатной, обязательно установить PdoTools).
- Один вызов: всё выводится через простой сниппет
{'PageBlocks' | snippet}или[[PageBlocks]]. - Скорость: кэшируется как обычный сниппет, не тормозит базу данных.
Почему не MIGX? В MIGX для каждого типа блока вам часто приходится создавать отдельные TV, конфигурации JSON и чанки. В PageBlocks TV-поля вообще не задействуются в привычном понимании. Вы создаете конфиг блока в красивом интерфейсе, привязываете чанк — и всё работает. Это быстрее в настройке и понятнее для контент-менеджера.
Установка и базовая настройка
Устанавливается обычно, из репозитория модекса:
- Пакеты → Установщик → Загрузить пакеты → Поиск: PageBlocks
- Устанавливаем бесплатную версию (автор Aleksandr Huz или boshnik)
После активации пакета, если вы зайдете на Главную или любую другую страницу сайта увидите вкладку PageBlocks.

Эта вкладка отвечает за создание и редактирования блоков. Ее можно переместить правее или отключить (к примеру на определенных шаблонах или страницах). Для этого идем в системные настройки и фильтруем их по названию пакета.

Здесь сразу рекомендую настроить следующее:
- Путь к файлам — pageblocks_source_path (при условии что основная папка с изображениями у вас не в assets/images/)
- Позиция вкладки PageBlocks — pageblocks_tab_index, поставить к примеру 1 (чтобы она стояла не первой, а сразу после вкладки Документ).
Ну и давайте разберем остальные настройки:
- Удаление файла — pageblocks_remove_file — Нет. Если установите Да, то при удалении изображений из заполненных блоков, они также будут удалятся физически с сервера.
- Запомнить ширину колонок — pageblocks_grid_stateful — Да. Типа запоминает ширину колонок сетки.
- Спрятать вкладку для родителей — pageblocks_hide_parents. Впишите ID родителей где не хотите чтобы она отображалась
- Спрятать вкладку для ресурсов — pageblocks_hide_resources и Спрятать вкладку для шаблонов — pageblocks_hide_templates. Тоже самое для ресурсов и шаблонов.
Типы полей для блоков и таблиц (ваш арсенал)
В бесплатной версии доступно 23 типа полей — этого более чем достаточно для 95 % задач: от простых лэндингов до сложных корпоративных сайтов с галереями, таблицами, кнопками и видео.

Мини документацию по ним, вы можете найти на оф сайте с документацией: pageblocks.boshnik.com, просто пощелкайте по плитке со скрина выше и попадете в интересующие типы полей.
Платная версия добавляет ещё 16 экзотических полей (вложенные блоки, repeater pro, карты и т.д.), но большинство разработчиков обходятся бесплатной версией.
Все поля выводятся в чанках через синтаксис Fenom: {$имя_поля} или {$имя_поля.подполе}. Если поле возвращает массив — используем {foreach} или модификаторы Fenom.
Таблица всех 23 типов полей + как их выводить
| № | Название поля (англ/рус) | Что это даёт | Вывод в Fenom (пример) | Полезные подполя / замечания |
|---|---|---|---|---|
| 1 | Text / Текст | Обычное однострочное поле | {$title} |
— |
| 2 | Textarea / Текстовая область | Большое текстовое поле без форматирования | {$description} |
— |
| 3 | Richtext / Текстовый редактор | TinyMCE с кнопками жирный/курсив/списки/ссылки | {$content} |
Автоматически очищается от скриптов |
| 4 | Ace / Редактор кода | Подсветка синтаксиса (HTML, CSS, JS, PHP и т.д.) | {$custom_css} |
Идеально для кастомных стилей блока |
| 5 | Number / Число | Только цифры, можно задать min/max | {$price} |
— |
| 6 | Date / Дата | Календарь, вывод в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС | {$event_date} |
Выводится в формате: 2024-02-17 01:15:00 |
| 7 | Time / Время | Только время | {$event_time} |
Выводится в формате: 01:30 |
| 8 | Select / Выпадающий список | Один вариант из списка | {$color} |
Значение = то, что вы задали в настройках |
| 9 | MultiSelect / Множественный выбор | Несколько вариантов | {foreach $colors as $color} |
Возвращает массив |
| 10 | Checkbox / Флажок | Да/Нет → 1 или 0 | {if $show_title} … {/if} |
— |
| 11 | Checkbox group / Группа флажков | Несколько независимых галочек | {foreach $colors as $color} |
Массив значений |
| 12 | Radio / Радиокнопки | Один вариант из группы | {$layout} |
— |
| 13 | Yes/No List / Да/Нет | Выпадающий список Да/Нет → 1 или 0 | {if $published == 1} … {/if} |
Удобно для включения/выключения блока |
| 14 | Resource list / Список ресурсов | Выбор страницы MODX | [[$resource_id]] или {$resource_id} |
Выводит ID ресурса |
| 15 | File / Файл | Загрузка любого файла | <a href="{$file}">Скачать PDF</a> |
Возвращает путь от корня сайта |
| 16 | Image / Изображение | Загрузка + превью + alt + размеры | <img src="{$image.url}" width="{$image.width}" height="{$image.height}" alt="{$image.alt}" loading="lazy"> |
Подполя: url, width, height, alt |
| 17 | Video / Видео | YouTube/Vimeo или своё видео | YouTube: <iframe src="{$video.embed}" …></iframe>Своё: <video><source src="{$video.url}"></video> |
embed — для YouTube, url + preview + extension — для своих видео |
| 18 | Button / Кнопка | Полноценная настраиваемая кнопка | {if $button.published} |
Все подполя можно распечатать {$button|print} |
| 19 | Color palette / Цветовая палитра | Выбор одного или нескольких цветов | {foreach $colors as $color}<div style="background:#{$color}"></div>{/foreach} |
Возвращает массив HEX без # |
| 20 | TableList / Таблица | Полноценная таблица с колонками и строками внутри блока | <table>{foreach $table as $row}<tr>{foreach $row as $cell}<td>{$cell}</td>{/foreach}</tr>{/foreach}</table> |
Или просто {foreach $table as $item}<li>{$item.title} — {$item.price}</li>{/foreach} |
| 21 | Hidden / Скрытое поле | Не видно в форме, но передаётся | {$hidden_value} |
Полезно для дефолтных классов, ID и т.д. |
| 22 | Readonly / Только чтение | Видно, но нельзя редактировать | {$version} |
Для номеров версий, дат создания и т.д. |
| 23 | Xtype / Произвольный xtype | Можно вставить ЛЮБОЕ стандартное поле MODX (например modx-combo-template) | Зависит от xtype — обычно {$fieldname} |
Список всех xtype: https://bobsguides.com/xtype-list.html |
- Image + Video — полностью заменяют Gallery и любые галереи;
- Button — 90 % кнопок на сайте делаются именно через это поле;
- TableList — вставляйте прайсы, сравнительные таблицы, характеристики товаров прямо в блок без отдельных TV;
- Color palette + MultiSelect — идеально для фильтров, тегов, категорий.
Быстрый способ отладки: что лежит внутри поля?
Вставьте в чанк временно:
<pre>
{$image|print}
{$button|print}
{$table|print}
</pre>
Получите полный массив со всеми подполями — дальше копируйте нужные ключи.
Подробная официальная документация по каждому полю (с скриншотами настроек) — здесь: pageblocks.boshnik.com/docs/
С этими 23 полями + Fenom вы сможете собрать любой блок из премиум шаблонов типа Porto — и всё будет редактироваться прямо в менеджере MODX без страха сломать верстку.
Обзор интерфейса: как создавать блоки и таблицы
Прежде чем писать код, давайте разберемся, как это выглядит в админке. Интерфейс PageBlocks интуитивен, но имеет свою логику: сначала мы конфигурируем блоки (как разработчик), а затем наполняем их (как контент-менеджер).
Весь процесс создания блоков происходит в: Пакеты → PageBlocks.

Есть еще выпадающая вкладка «Конструктор блоков», она ведет туда же.
1. Создание нового блока (Конфигурация)
Зайдя в компонент, вы увидите вкладку «Блоки». Здесь хранится библиотека всех возможных секций вашего сайта.
- Нажмите кнопку «Создать».
- Откроется окно с обязательными полями и тремя вкладками:
- Обязательные поля. Здесь задаем Имя (понятное менеджеру, например «Слайдер») и Чанк (например
pb.slider). - Вкладка «Поля» (открыта по умолчанию). Самое важное место. Здесь мы «накидываем» структуру блока.
- Вкладка «Вкладки». Редко используемое (по крайней мере у меня), суть в том что вы здесь можете создать различные вкладки, например Основные данные и Данные оформления (я так иногда делаю для сложных блоков), далее Разнести поля по этим вкладкам (к примеру задание классов блоков в Данные оформления, а поля контента соответственно в Основные данные).
- Вкладка «Доступность». Здесь можно ограничить блок (например, показывать блок «Слайдер» только на ресурсе с ID=1).
- Обязательные поля. Здесь задаем Имя (понятное менеджеру, например «Слайдер») и Чанк (например
2. Добавление полей (Visual Builder)
Во вкладке «Поля» нажимаете «Создать». В сплывающем окне, заполняем (* отмечены обязательные для заполнения):

- Тип поля*: Текст, Изображение, Видео, Richtext и т.д. — рассматривали выше;
- Вкладка: — (ну или выбираем созданные, если вы их создавали);
- Подпись: то, что увидит менеджер (например, «Заголовок секции»).
- Название*: например
title(допускаются только латинские буквы в нижнем регистре), название будет ключом для вывода; - Значение по умолчанию: -, но если хотите чтобы поле было предварительно забитое какими либо данными, можете указать, в нашем случае «Album example»
- Ширина поля: 100 — это во всю ширину, можете сделать 50 и т.п., я обычно не трогаю.
- Описание поля: -, или например «Название заголовка (h1)»
- Включено: да, если уберете галку то будет недоступно, пока обратно не влючите.
- Обязательное поле: -, если поле обязательно должно быть заполнено, то ставим галку
- Ну и Сохранить или Закрыть (тогда ничего не сохранится)
Такие настройки у большинства полей, но у кнопок, видео и т.п. вы увидите другие.
3. Настройка сетки и вкладок (опционально)
Если полей много, их можно сгруппировать.
- Ширина поля: по умолчанию 100%. Можно поставить 50%, и тогда два поля встанут в один ряд.
- Вкладки: можно создать вкладки «Контент» и «Настройки» (например, чтобы спрятать выбор цвета фона или отступы во вторую вкладку, не перегружая менеджера).
4. Создание таблиц и полей с типом TableList — замена MIGX
Это самый важный шаг для создания списков, слайдеров, галерей и сеток карточек. TableList работает как «матрешка» — это конструктор внутри конструктора.
Алгоритм действий:
- На вкладке Таблицы, создаете создаете и заполняете таблицу полями:

Принцип тот же что у добавления полей. - Настраиваете сетку таблицы (опционально). Делается это во вкладке «Столбцы сетки». Жмем создать, выбираем созданное поле, рендер при необходимости (только для изображений, дат, кнопок).

И сохраняете. - После того как создали таблицу, создайте поле с типом «Таблица».
- Назовите его, так же как и таблицу
table_slider, а в описании укажите например: Добавить слайды. - Сохраните поле (нажмите «Сохранить» в окне поля).
В итоге у вас получается блок с полем, внутри которого живет таблица с собственным набором полей.
5. Заполнение контентом (вид из ресурса)
После того как блок создан, идем в любой Ресурс (страницу) во вкладку PageBlocks.
- Жмем «Добавить блок».
- Выбираем из списка наш только что созданный блок.

- Он появляется в списке. Мы можем его развернуть, заполнить поля, свернуть.

- Если блоков несколько — мы можем менять их местами, просто перетаскивая мышкой.
- Есть кнопка «Вкл/Выкл» (глаз) — чтобы временно скрыть блок на сайте, не удаляя контент.
Теперь, понимая куда нажимать, давайте соберем реальную страницу на Bootstrap 5.
Практика: интеграция шаблона «Small Business»
Перейдем от теории к делу. Возьмем простенький довольно популярный бесплатный шаблон Small Business от Start Bootstrap.

Задача: превратить статичный HTML в динамический конструктор, чтобы менеджер мог менять тексты, картинки и количество карточек, не залезая в код.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Small Business - Start Bootstrap Template</title>
<!-- Favicon-->
<link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
<!-- Core theme CSS (includes Bootstrap)-->
<link href="css/styles.css" rel="stylesheet" />
</head>
<body>
<!-- Responsive navbar-->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container px-5">
<a class="navbar-brand" href="#!">Start Bootstrap</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#!">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#!">About</a></li>
<li class="nav-item"><a class="nav-link" href="#!">Contact</a></li>
<li class="nav-item"><a class="nav-link" href="#!">Services</a></li>
</ul>
</div>
</div>
</nav>
<!-- Page Content-->
<div class="container px-4 px-lg-5">
<!-- Heading Row-->
<div class="row gx-4 gx-lg-5 align-items-center my-5">
<div class="col-lg-7"><img class="img-fluid rounded mb-4 mb-lg-0" src="https://dummyimage.com/900x400/dee2e6/6c757d.jpg" alt="..." /></div>
<div class="col-lg-5">
<h1 class="font-weight-light">Business Name or Tagline</h1>
<p>This is a template that is great for small businesses. It doesn't have too much fancy flare to it, but it makes a great use of the standard Bootstrap core components. Feel free to use this template for any project you want!</p>
<a class="btn btn-primary" href="#!">Call to Action!</a>
</div>
</div>
<!-- Call to Action-->
<div class="card text-white bg-secondary my-5 py-4 text-center">
<div class="card-body"><p class="text-white m-0">This call to action card is a great place to showcase some important information or display a clever tagline!</p></div>
</div>
<!-- Content Row-->
<div class="row gx-4 gx-lg-5">
<div class="col-md-4 mb-5">
<div class="card h-100">
<div class="card-body">
<h2 class="card-title">Card One</h2>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem magni quas ex numquam, maxime minus quam molestias corporis quod, ea minima accusamus.</p>
</div>
<div class="card-footer"><a class="btn btn-primary btn-sm" href="#!">More Info</a></div>
</div>
</div>
<div class="col-md-4 mb-5">
<div class="card h-100">
<div class="card-body">
<h2 class="card-title">Card Two</h2>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quod tenetur ex natus at dolorem enim! Nesciunt pariatur voluptatem sunt quam eaque, vel, non in id dolore voluptates quos eligendi labore.</p>
</div>
<div class="card-footer"><a class="btn btn-primary btn-sm" href="#!">More Info</a></div>
</div>
</div>
<div class="col-md-4 mb-5">
<div class="card h-100">
<div class="card-body">
<h2 class="card-title">Card Three</h2>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem magni quas ex numquam, maxime minus quam molestias corporis quod, ea minima accusamus.</p>
</div>
<div class="card-footer"><a class="btn btn-primary btn-sm" href="#!">More Info</a></div>
</div>
</div>
</div>
</div>
<!-- Footer-->
<footer class="py-5 bg-dark">
<div class="container px-4 px-lg-5"><p class="m-0 text-center text-white">Copyright © Your Website 2023</p></div>
</footer>
<!-- Bootstrap core JS-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Core theme JS-->
<script src="js/scripts.js"></script>
</body>
</html>
1. Анализ и «нарезка» шаблона
Посмотрев на исходный код body, мы видим классическую структуру. Сразу разделим её на Сквозные элементы (которые есть на всех страницах) и Динамические блоки (контент PageBlocks).
Сквозные элементы (не кладем в PageBlocks):
- Navbar (
<nav>): Меню сайта. Обычно выносится в чанкtpl.headerи собирается через сниппетpdoMenu. - Footer (
<footer>): Подвал сайта. Выносится в чанкtpl.footer.
Динамические блоки (кладем в PageBlocks): Оставшуюся центральную часть (div.container) мы разобьем на три логических блока:
- Heading Row — Приветственный блок (картинка слева, текст справа).
- Call to Action — Синяя полоска с призывом.
- Content Row — Три карточки с услугами.
2. Создаем Блок 1: «Приветствие» (Heading Row)
В оригинале это row с картинкой и текстом.
HTML исходник:
<div class="row gx-4 gx-lg-5 align-items-center my-5">
<div class="col-lg-7"><img class="img-fluid rounded mb-4 mb-lg-0" src="..." alt="..." /></div>
<div class="col-lg-5">
<h1 class="font-weight-light">Business Name or Tagline</h1>
<p>This is a template that is great for small businesses...</p>
<a class="btn btn-primary" href="#!">Call to Action!</a>
</div>
</div>
Это простой блок, без вложенных таблиц.
Настройка в PageBlocks. Создаем блок «Приветствие» (чанк pb.heading). Добавляем поля:

image(Тип: Изображение) — Фото слева.title(Тип: Текст) — Заголовок H1.text(Тип: Текстовый редактор) — Основной текст.button(Тип: Кнопка) — Кнопка призыва.
Чанк pb.heading (Fenom):
<div class="row gx-4 gx-lg-5 align-items-center my-5">
<div class="col-lg-7">
{if $image}
<img class="img-fluid rounded mb-4 mb-lg-0" src="{$image.url}" alt="{$image.title}" width="900" height="400" />
{/if}
</div>
<div class="col-lg-5">
{if $title}<h1 class="font-weight-light">{$title}</h1>{/if}
{if $text}<p>{$text}</p>{/if}
{if $button.text}
<a class="btn btn-primary" href="{$button.href}" {if $button.target_blank}target="_blank"{/if}>
{$button.text}
</a>
{/if}
</div>
</div>
3. Создаем Блок 2: «Call to Action»
Это максимально простой текстовый блок на сером фоне.
HTML исходник:
<div class="card text-white bg-secondary my-5 py-4 text-center">
<div class="card-body"><p class="text-white m-0">This call to action card...</p></div>
</div>
Настройка в PageBlocks: Создаем блок «Призыв к действию» (чанк pb.cta).
text(Тип: Текст) — Текст внутри плашки.
Чанк pb.cta (Fenom):
<div class="card text-white bg-secondary my-5 py-4 text-center">
<div class="card-body">
<p class="text-white m-0">{$text}</p>
</div>
</div>
4. Создаем Блок 3: «Карточки услуг» (Content Row)
Самый интересный блок. В HTML у нас три одинаковых col-md-4. Ни в коем случае не создавайте поля title_1, title_2, title_3! Мы используем поле TableList, чтобы менеджер мог добавить хоть 3, хоть 10 карточек.
HTML исходник (одной карточки):
<div class="col-md-4 mb-5">
<div class="card h-100">
<div class="card-body">
<h2 class="card-title">Card One</h2>
<p class="card-text">Lorem ipsum...</p>
</div>
<div class="card-footer"><a class="btn btn-primary btn-sm" href="#!">More Info</a></div>
</div>
</div>
Настройка в PageBlocks:
Первым делом создаем Таблицу table_items, со следующими полями:
title(Тип: Текст) — Заголовок.text(Тип: Текстовая область) — Текст.link(Тип: Текст или Resource List для выбора ID страницы) — Ссылка.
И соответственно сетку (столбцы) для нее.

После этого создаем блок «Сетка услуг» (чанк pb.services).
- Создаем поле с названием
table_items. - Тип поля: Таблица.
- Подпись: Добавить услуги
- Выбираем созданную таблицу и сохраняем.

Чанк pb.services (Fenom):
<div class="row gx-4 gx-lg-5">
{* Запускаем цикл по строкам таблицы TableList *}
{foreach $table_items as $item}
<div class="col-md-4 mb-5">
<div class="card h-100">
<div class="card-body">
<h2 class="card-title">{$item.title}</h2>
<p class="card-text">{$item.text}</p>
</div>
<div class="card-footer">
<a class="btn btn-primary btn-sm" href="{$item.link}">More Info</a>
</div>
</div>
</div>
{/foreach}
</div>
5. Собираем всё в шаблоне страницы
Теперь идем в основной шаблон сайта (Template) и собираем конструктор воедино.
<!DOCTYPE html>
<html lang="ru">
<head>
{* Мета-теги MODX *}
<title>[[*pagetitle]] - [[++site_name]]</title>
<meta name="description" content="[[*description]]">
<link href="css/styles.css" rel="stylesheet" />
</head>
<body>
[[$tpl.navbar]]
<div class="container px-4 px-lg-5">
[[PageBlocks]]
</div>
[[$tpl.footer]]
<script src="js/scripts.js"></script>
</body>
</html>
Итог. Мы потратили 15 минут. Теперь, если менеджер захочет поменять заголовок, удалить кнопку «Call to Action» или добавить четвертую услугу в ряд — он сделает это мышкой в админке. Верстка при этом останется идеальной.
Дополнительно: сажаем Bootstrap Carrusel (слайдер)
Для закрепления материала реализуем один из самых сложных элементов для верстки в CMS — слайдер с индикаторами (точками) и стрелками.

<div id="carouselExampleCaptions" class="carousel slide">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<img src="..." class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>Первый слайд label</h5>
<p>Некоторый репрезентативный контент-заполнитель для первого слайда</p>
</div>
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>Второй слайд label</h5>
<p>Некоторый репрезентативный контент-заполнитель для второго слайда</p>
</div>
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>Третий слайд label</h5>
<p>Некоторый репрезентативный контент-заполнитель для третьего слайда</p>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleCaptions" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
В чем сложность?
- У индикаторов должна быть нумерация:
data-bs-slide-to="0","1","2". - У первого слайда и первого индикатора должен быть класс
active, у остальных — нет.
Без Феном это требовало бы сниппетов или сложных плейсхолдеров [[+idx]]. А с Fenom это делается элементарно.
1. Настройка в PageBlocks:
Создаем таблицу table_carousel со следующими полями:
image(Изображение);title(Текст) — Заголовок слайда;text(Текстовая область) — Описание.
И сразу создайте столбцы таблицы, не забудьте для изображения поставить рендер: renderImage.
Далее создайте блок «Слайдер на главной». Чанк: pb.carousel. Нам понадобится всего одно поле типа TableList, так как слайды — это повторяющийся список.
- Поле:
table_carousel - Тип: Таблица и выберите эту таблицу.
2. Чанк pb.carousel с логикой Fenom
Используем синтаксис {foreach $array as $index => $value}, где $index автоматически будет считать номера (0, 1, 2…), которые нам так нужны для Bootstrap.
{* Задаем уникальный ID для слайдера, чтобы не конфликтовал, если их несколько *}
{var $sliderId = 'carousel_' ~ $id}
<div id="{$sliderId}" class="carousel slide">
<div class="carousel-indicators">
{foreach $table_carousel as $idx => $slide}
<button type="button" data-bs-target="#{$sliderId}" data-bs-slide-to="{$idx}"{if $idx == 0} class="active" aria-current="true"{/if} aria-label="Slide {$idx + 1}"></button>
{/foreach}
</div>
<div class="carousel-inner">
{foreach $table_carousel as $idx => $slide}
<div class="carousel-item{if $idx == 0} active{/if}">
<img src="{$slide.image.url}" class="d-block w-100" alt="{$slide.title}">
<div class="carousel-caption d-none d-md-block">
{if $slide.title}<h5>{$slide.title}</h5>{/if}
{if $slide.text}<p>{$slide.text}</p>{/if}
</div>
</div>
{/foreach}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#{$sliderId}" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#{$sliderId}" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
Что мы сделали:
{foreach $table_carousel as $idx => $slide}— запустили цикл, где$idxэто 0, 1, 2…class="{if $idx == 0}active{/if}"— если это первый проход цикла (индекс 0), добавляем классactive.- Использовали переменную
{$sliderId}, чтобы привязать кнопки именно к этому слайдеру.
Заключение
PageBlocks Free — это сейчас самый быстрый и удобный способ делать лендинги и корпоративные сайты на MODX: один шаблон, бесконечное количество блоков, редактирование клиентом без страха сломать верстку.












