MODX PageBlocks Free: документация по компоненту для быстрой посадки верстки

PageBloks Free Дополнения

Хотите собрать главную страницу сайта или лендинг на MODX, не дублируя десятки чанков и не создавая бесконечные TV-поля? Знакомьтесь с PageBlocks (Free версия). Это идеальный «конструктор блоков», который превращает админку MODX в подобие Tilda или Elementor, но с полным контролем над кодом.

В этой статье разберем, как бесплатно и быстро развернуть удобный конструктор, который работает на MODX 3.x, PHP 8.2+ и летает благодаря Fenom.

Что такое PageBlocks Free и почему он лучше MIGX

PageBlocks — это компонент от Александра Хуза (boshnik), который меняет подход к сборке страниц.

Главные фишки Free-версии:

  • Неограниченное количество блоков на странице.
  • Drag & Drop: менеджеры могут менять блоки местами простым перетаскиванием.
  • Fenom из коробки*: не нужно ставить дополнительные парсеры (*в платной версии, для бесплатной, обязательно установить PdoTools).
  • Один вызов: всё выводится через простой сниппет {'PageBlocks' | snippet} или [[PageBlocks]].
  • Скорость: кэшируется как обычный сниппет, не тормозит базу данных.

Почему не MIGX? В MIGX для каждого типа блока вам часто приходится создавать отдельные TV, конфигурации JSON и чанки. В PageBlocks TV-поля вообще не задействуются в привычном понимании. Вы создаете конфиг блока в красивом интерфейсе, привязываете чанк — и всё работает. Это быстрее в настройке и понятнее для контент-менеджера.

Установка и базовая настройка

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

  1. Пакеты → Установщик → Загрузить пакеты → Поиск: PageBlocks
  2. Устанавливаем бесплатную версию (автор Aleksandr Huz или boshnik)

После активации пакета, если вы зайдете на Главную или любую другую страницу сайта увидите вкладку PageBlocks.

Вкладка PageBloks

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

Фильтруем настройки конструктора в системных настройках

Здесь сразу рекомендую настроить следующее:

  • Путь к файлам — 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}
{$color}
{/foreach}
Возвращает массив
10 Checkbox / Флажок Да/Нет → 1 или 0 {if $show_title} … {/if}
11 Checkbox group / Группа флажков Несколько независимых галочек {foreach $colors as $color}
{$color}
{/foreach}
Массив значений
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}
<a
href="{$button.href?:($button.resource|resource:'uri')}"
class="btn {$button.classes}"
{$button.attr}
{if $button.target_blank} target="_blank"{/if}
>
{$button.text}
</a>
{/if}
Все подполя можно распечатать {$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
Самые мощные поля, которые заменяют MIGX:
  • 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. Создание нового блока (Конфигурация)

Зайдя в компонент, вы увидите вкладку «Блоки». Здесь хранится библиотека всех возможных секций вашего сайта.

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

2. Добавление полей (Visual Builder)

Во вкладке «Поля» нажимаете «Создать». В сплывающем окне, заполняем (* отмечены обязательные для заполнения):

Окно добавления поля

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

Такие настройки у большинства полей, но у кнопок, видео и т.п. вы увидите другие.

3. Настройка сетки и вкладок (опционально)

Если полей много, их можно сгруппировать.

  • Ширина поля: по умолчанию 100%. Можно поставить 50%, и тогда два поля встанут в один ряд.
  • Вкладки: можно создать вкладки «Контент» и «Настройки» (например, чтобы спрятать выбор цвета фона или отступы во вторую вкладку, не перегружая менеджера).

4. Создание таблиц и полей с типом TableList — замена MIGX

Это самый важный шаг для создания списков, слайдеров, галерей и сеток карточек. TableList работает как «матрешка» — это конструктор внутри конструктора.

Алгоритм действий:

  1. На вкладке Таблицы, создаете создаете и заполняете таблицу полями:
    Создание и заполнение таблицы
    Принцип тот же что у добавления полей.
  2. Настраиваете сетку таблицы (опционально). Делается это во вкладке «Столбцы сетки». Жмем создать, выбираем созданное поле, рендер при необходимости (только для изображений, дат, кнопок).
    Столбцы сетки
    И сохраняете.
  3. После того как создали таблицу, создайте поле с типом «Таблица».
  4. Назовите его, так же как и таблицу table_slider, а в описании укажите например: Добавить слайды.
  5. Сохраните поле (нажмите «Сохранить» в окне поля).

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

5. Заполнение контентом (вид из ресурса)

После того как блок создан, идем в любой Ресурс (страницу) во вкладку PageBlocks.

  • Жмем «Добавить блок».
  • Выбираем из списка наш только что созданный блок.
    Выбор блоков
  • Он появляется в списке. Мы можем его развернуть, заполнить поля, свернуть.
    Пример полей заполнения блока
  • Если блоков несколько — мы можем менять их местами, просто перетаскивая мышкой.
  • Есть кнопка «Вкл/Выкл» (глаз) — чтобы временно скрыть блок на сайте, не удаляя контент.

Теперь, понимая куда нажимать, давайте соберем реальную страницу на Bootstrap 5.

Практика: интеграция шаблона «Small Business»

Перейдем от теории к делу. Возьмем простенький довольно популярный бесплатный шаблон Small Business от Start Bootstrap.

small business

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

Полный 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 &copy; 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):

  1. Navbar (<nav>): Меню сайта. Обычно выносится в чанк tpl.header и собирается через сниппет pdoMenu.
  2. Footer (<footer>): Подвал сайта. Выносится в чанк tpl.footer.

Динамические блоки (кладем в PageBlocks): Оставшуюся центральную часть (div.container) мы разобьем на три логических блока:

  1. Heading Row — Приветственный блок (картинка слева, текст справа).
  2. Call to Action — Синяя полоска с призывом.
  3. 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).

  1. Создаем поле с названием table_items.
  2. Тип поля: Таблица.
  3. Подпись: Добавить услуги
  4. Выбираем созданную таблицу и сохраняем.
    Создаем блок сетка услуг

Чанк 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 — слайдер с индикаторами (точками) и стрелками.

carousel с индикаторами, подписями и контролами

HTML код слайдера
<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>

В чем сложность?

  1. У индикаторов должна быть нумерация: data-bs-slide-to="0", "1", "2".
  2. У первого слайда и первого индикатора должен быть класс active, у остальных — нет.

Без Феном это требовало бы сниппетов или сложных плейсхолдеров [[+idx]]. А с Fenom это делается элементарно.

1. Настройка в PageBlocks:

Создаем таблицу table_carousel со следующими полями:

  • image (Изображение);
  • title (Текст) — Заголовок слайда;
  • text (Текстовая область) — Описание.

И сразу создайте столбцы таблицы, не забудьте для изображения поставить рендер: renderImage.

Далее создайте блок «Слайдер на главной». Чанк: pb.carousel. Нам понадобится всего одно поле типа TableList, так как слайды — это повторяющийся список.

  1. Поле: table_carousel
  2. Тип: Таблица и выберите эту таблицу.

Используем синтаксис {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}, чтобы привязать кнопки именно к этому слайдеру.
Часто задаваемые вопросы (FAQ)
Сколько блоков можно выводить на одной странице?
А если нужно 100 разных блоков?
Есть ли платная версия?
Тормозит ли сайт?

Заключение

PageBlocks Free — это сейчас самый быстрый и удобный способ делать лендинги и корпоративные сайты на MODX: один шаблон, бесконечное количество блоков, редактирование клиентом без страха сломать верстку.

Оцените статью
MODX 3
Добавить комментарий

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