MIGX в MIGX: создаем редактор блоков страницы

Редактор блоков страницы на MIGX с вложенными записями MODX Revo

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

Например, редактор добавляет текстовый блок, затем отзывы, меняет их порядок и заполняет содержание. Для каждой секции используется своя конфигурация, а все записи хранятся в одном общем TV.

В этой статье используем Multiple Formtabs и вывод через Fenom. Это дополнительный разбор возможностей компонента, а не обязательная переделка уже работающего Creative.

Примеры оформления ниже сохранены из прежней практики. Для Creative и другой HTML-основы нужно использовать их собственную разметку и библиотеки. Первый экран и About из предыдущего урока автоматически переносить в этот редактор не требуется.

Что потребуется для примера

Нужны установленный MIGX, совместимая версия pdoTools и настроенная обработка Fenom. Ace пригодится для редактирования кода в админке.

В этом варианте код цикла размещается непосредственно в шаблоне, а оформление секций — в чанках, обрабатываемых pdoTools:

  • pdotools_fenom_parser — обработка Fenom непосредственно в шаблоне страницы.
  • pdotools_fenom_default — обработка Fenom в чанках pdoTools.

Для приведенных примеров не требуется включать расширенный доступ через pdotools_fenom_php и pdotools_fenom_modx. Подробная настройка разобрана в уроке Fenom.

Настройки Fenom в прежней версии интерфейса MODX

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

Перед этим упражнением нужно понимать конфигурации MIGX, TV, чанки и вложенные записи. Если эти понятия пока вызывают вопросы, сначала пройдите основной урок MIGX.

Видео, на котором основана первая версия статьи

Первая версия статьи подготовлена по стороннему видео «Неоднородное содержимое или конфигуратор лендингов». Видео не мое; сохраняю его как дополнительный материал. Названия полей и оформление могут отличаться от примеров ниже.

Подготавливаем конфигурации отдельных блоков

Для редактора достаточно двух разных типов секций. Необязательно заранее создавать три блока или фиксированное количество конфигураций.

В примере используем:

  • about — текстовая секция с кнопкой и изображением.
  • testimonials — секция отзывов с вложенным списком.
  • testimonials_config — конфигурация одного вложенного отзыва.

Создайте их через менеджер конфигураций MIGX по порядку из предыдущего урока. Если такие конфигурации уже существуют, сначала сравните имена и поля, а не создавайте дубликаты.

Конфигурация Поля
about title, subtitle, text, link, name_buttons, image.
testimonials title, subtitle, slides.
testimonials_config text_reviews, name, professiya, foto.

Для коротких строк используйте текстовый ввод, для описаний — текстовую область, для image и foto — тип image.

У поля slides выберите тип migx и в Configs укажите testimonials_config. Так форма секции отзывов будет содержать собственный список записей.

В приведенных чанках описания выводятся как обычный текст. Если выбираете richtext и хотите сохранять HTML, потребуется отдельно согласовать способ его вывода.

Для изображений в этом примере используем сохраненные пути относительно корня проекта, например assets/img/example.jpg, без начального слеша. Если у вас другой источник или формат значений, подготовку адресов нужно изменить.

Пример созданных конфигураций MIGX из прежней практики

На архивном снимке конфигураций может быть больше. Для текущего упражнения нужны две внешние формы и конфигурация вложенного отзыва.

Создаем общую конфигурацию редактора

В менеджере MIGX добавьте еще одну конфигурацию:

  • Name: config.
  • Замена надписи «Добавить элемент»: Добавить блок.
  • Window Title: Редактор блоков.

Если имя config уже занято в вашем проекте, выберите другое и замените его во всех связанных местах инструкции.

Создание общей конфигурации редактора MIGX

Перейдите на Formtabs. В Multiple Formtabs выберите основные конфигурации about и testimonials. В Multiple Formtabs Label укажите «Выберите блок».

Выбор конфигураций в Multiple Formtabs

Добавляем только конфигурации целых секций. testimonials_config здесь не нужен: его использует вложенное поле slides. Не добавляйте одну и ту же конфигурацию одновременно как секцию и как ее внутреннюю запись без отдельной задачи.

При использовании Multiple Forms у записи появляется поле MIGX_formname. Оно определяет выбранный тип формы. В этом примере ожидаем значения about и testimonials; ниже проверим их в сохраненных данных.

Если в настройках конфигураций используются Multiple Formtabs Optionsvalue, задайте соответствующие значения about и testimonials. Подпись в списке выбора и техническое значение типа — не обязательно одно и то же.

На вкладке Columns добавьте колонку:

  • Header: Тип блока.
  • Field: MIGX_formname.

Колонка MIGX_formname в общей конфигурации

Сохраните колонку и всю конфигурацию.

Пример списка конфигураций MIGX

Создаем TV для редактора блоков

При необходимости создайте категорию page builder, чтобы сгруппировать элементы. На работу вывода название категории не влияет.

Создание категории элементов MODX

Создайте TV:

  • Имя: config.
  • Подпись: Блоки страницы.
  • Категория: page builder или ваша существующая категория.

Создание TV для списка блоков

В параметрах ввода выберите тип migx, а в конфигурациях укажите config. Назначьте TV нужному шаблону и сохраните.

Подключение конфигурации config к MIGX TV

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

Заново откройте ресурс с назначенным шаблоном. В дополнительных полях должен появиться список блоков с выбором формы.

Выбор типа блока в общем MIGX TV

Добавьте одну запись About, заполните ее поля и сохраните. Затем добавьте секцию отзывов, заполните ее заголовки и несколько вложенных отзывов.

Сохраните вложенные записи, внешние записи блоков и затем сам ресурс.

Пример заполненного списка блоков

В этом учебном примере добавляем по одной секции каждого типа. Их разметка содержит фиксированные ID about и testimonials. Для нескольких копий одного типа потребуется отдельно подготовить уникальные ID и проверить инициализацию JavaScript.

Проверяем структуру сохраненных данных

На локальной копии или закрытой тестовой странице временно добавьте в шаблон:

{set $blocks = $_modx->resource.config | fromJSON}
{$blocks | print}

Откройте страницу. Должен появиться массив заполненных блоков.

Пример массива данных MIGX с типами блоков

Найдите поле MIGX_formname у каждой внешней записи. Не путайте его с опечаткой MIGX_forname: для нашего вывода используется именно MIGX_formname.

Остальные ключи — имена полей конфигурации. Вложенный список slides содержит JSON, который нужно отдельно преобразовать перед циклом по отзывам.

Если значения типа отличаются от about и testimonials, сначала согласуйте их с настройками форм и кодом вывода. Не ориентируйтесь только на видимую подпись в выпадающем списке.

Отладочный вывод может раскрыть заполненные данные страницы. Не оставляйте его на общедоступном сайте. После проверки удалите вызов print и замените диагностический блок рабочим выводом из последнего раздела.

Создаем чанк блока About

Создайте обычный чанк с именем about. Он получит текущую запись через переменную data:

<section id="about" class="about">
    <div class="container" data-aos="fade-up">
        <div class="row gx-0">
            <div class="col-lg-6 d-flex flex-column justify-content-center"
                 data-aos="fade-up" data-aos-delay="200">
                <div class="content">
                    {if $data.subtitle}
                        <h3>{$data.subtitle | escape}</h3>
                    {/if}

                    <h2>{$data.title | escape}</h2>
                    <p>{$data.text | escape | nl2br}</p>

                    {if $data.link && $data.name_buttons}
                        <div class="text-center text-lg-start">
                            <a href="{$data.link | escape}"
                               class="btn-read-more d-inline-flex align-items-center justify-content-center align-self-center">
                                <span>{$data.name_buttons | escape}</span>
                                <i class="bi bi-arrow-right" aria-hidden="true"></i>
                            </a>
                        </div>
                    {/if}
                </div>
            </div>

            <div class="col-lg-6 d-flex align-items-center"
                 data-aos="zoom-out" data-aos-delay="200">
                {if $data.image}
                    <img src="{$_modx->config.base_url | escape}{$data.image | escape}"
                         class="img-fluid" alt="{$data.title | escape}">
                {/if}
            </div>
        </div>
    </div>
</section>

Сохраните чанк. Обращение вида {$data.title} получает поле текущей записи блока, а не стандартное поле ресурса.

Текстовые значения экранируем. Ссылки должны содержать допустимые адреса: экранирование HTML не проверяет протокол и назначение URL.

Условие вокруг подзаголовка убирает весь тег, если поле пустое. Условие кнопки проверяет и адрес, и подпись.

Создаем чанк отзывов с вложенным списком

Создайте чанк с именем testimonials. В нем сначала выводим поля секции, затем преобразуем slides и перебираем вложенные записи:

{set $items = $data.slides | fromJSON}

<section id="testimonials" class="testimonials">
    <div class="container" data-aos="fade-up">
        <header class="section-header">
            <h2>{$data.title | escape}</h2>
            {if $data.subtitle}
                <p>{$data.subtitle | escape}</p>
            {/if}
        </header>

        {if $items}
            <div class="testimonials-slider swiper"
                 data-aos="fade-up" data-aos-delay="200">
                <div class="swiper-wrapper">
                    {foreach $items as $item}
                        <div class="swiper-slide">
                            <div class="testimonial-item">
                                <div class="stars" aria-hidden="true">
                                    <i class="bi bi-star-fill"></i>
                                    <i class="bi bi-star-fill"></i>
                                    <i class="bi bi-star-fill"></i>
                                    <i class="bi bi-star-fill"></i>
                                    <i class="bi bi-star-fill"></i>
                                </div>

                                <p>{$item.text_reviews | escape | nl2br}</p>

                                <div class="profile mt-auto">
                                    {if $item.foto}
                                        <img src="{$_modx->config.base_url | escape}{$item.foto | escape}"
                                             class="testimonial-img"
                                             alt="{$item.name | escape}">
                                    {/if}
                                    <h3>{$item.name | escape}</h3>
                                    <h4>{$item.professiya | escape}</h4>
                                </div>
                            </div>
                        </div>
                    {/foreach}
                </div>
                <div class="swiper-pagination"></div>
            </div>
        {/if}
    </div>
</section>

Сохраните чанк.

Здесь data — внешняя запись секции, а item — один вложенный отзыв. Список проверяем после fromJSON, а не только по наличию текста в поле: строка [] может содержать пустой массив.

Пять звезд сохранены как часть демонстрационного оформления. Это статические иконки, а не рассчитанный рейтинг.

Разметка отзывов зависит от CSS и JavaScript исходной верстки, включая Swiper, иконки и AOS. MIGX не подключает и не запускает их автоматически. Если вам нужен самостоятельный пример карусели, используйте урок слайдеров.

Как учитывать пути изображений

В чанках выше к значениям image и foto добавляется base_url. Это рассчитано на сохраненные пути относительно корня проекта, например assets/img/example.jpg.

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

Это особенность прямого вывода сохраненного JSON, а не утверждение, что MIGX вообще не умеет работать с источниками. В getImageList предусмотрена обработка полей по конфигурации TV, а прямой цикл Fenom не повторяет ее автоматически.

Пример поля изображения в прежней конфигурации MIGX

Если адрес неверный, сначала посмотрите фактическое сохраненное значение и получившийся src. Подробности разобраны в разделе об изображениях основного урока MIGX.

Архивный пример: блок с Bootstrap-каруселью

В прежней версии статьи использовался еще один тип блока со списком bs_carusel. Сохраняю его как дополнительный пример вложенного массива, а не обязательную часть текущего упражнения.

Структура данных карусели из прежнего примера

Фрагмент ниже относится к прежнему варианту Bootstrap с атрибутами data-ride и data-slide. Не вставляйте его в Creative на Bootstrap 5 без адаптации разметки и проверки JavaScript.

В этом отдельном архивном примере поле slide содержит имя файла, а изображения находятся в каталоге img/ от корня проекта. Если ваши значения устроены иначе, измените подготовку пути.

{set $items = $data.bs_carusel | fromJSON}

{if $items}
    <div id="carouselExampleCaptions" class="carousel slide" data-ride="carousel">
        <div class="carousel-inner">
            {foreach $items as $idx => $item}
                <div class="carousel-item{if $idx == 0} active{/if}">
                    <img src="{$_modx->config.base_url | escape}img/{$item.slide | escape}"
                         class="d-block w-100"
                         alt="{$item.zagolovok | escape}">
                    <div class="carousel-caption d-none d-md-block">
                        <h5>{$item.zagolovok | escape}</h5>
                        <p>{$item.opisanie | escape}</p>
                    </div>
                </div>
            {/foreach}
        </div>

        <a class="carousel-control-prev" href="#carouselExampleCaptions"
           role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Предыдущий</span>
        </a>
        <a class="carousel-control-next" href="#carouselExampleCaptions"
           role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Следующий</span>
        </a>
    </div>
{/if}

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

Выводим блоки на странице

Удалите временный диагностический вывод и поставьте на его место:

{set $blocks = $_modx->resource.config | fromJSON}

{if $blocks}
    {foreach $blocks as $block}
        {if $block.MIGX_formname == 'about'}
            {'about' | chunk : [
                'data' => $block
            ]}
        {elseif $block.MIGX_formname == 'testimonials'}
            {'testimonials' | chunk : [
                'data' => $block
            ]}
        {/if}
    {/foreach}
{/if}

Каждая запись передается в свой чанк через параметр data. Блоки выводятся в порядке списка MIGX.

Вместо вызова произвольного чанка по любому значению из данных здесь явно разрешены два типа: about и testimonials. Если добавляете новую форму, дополните соответствие в коде вывода.

Незнакомый тип в этом примере не выводится. Если секция пропала, сначала сравните фактическое значение MIGX_formname с условиями, а затем проверьте имя и содержание чанка.

Разместите общий вывод вместо прежних статических секций или их отдельных вызовов. Не оставляйте оба способа одновременно: иначе блоки продублируются.

Multiple Forms не требует именно Fenom. MIGX также умеет выбирать обычный чанк по полю через &tpl=`@FIELD:MIGX_formname`. Но такие чанки должны использовать подходящий для этого способа синтаксис. Нельзя просто заменить наш Fenom-цикл этим параметром и ожидать, что все примеры станут взаимозаменяемыми.

Проверяем редактор блоков

  1. Измените заголовок одного блока и сохраните запись и ресурс.
  2. Поменяйте порядок двух внешних записей и проверьте порядок на сайте.
  3. Добавьте отзыв внутри секции и проверьте его появление.
  4. Очистите необязательный подзаголовок: его пустой тег не должен оставаться.
  5. Проверьте адреса изображений и загрузку библиотек исходного оформления.
  6. Убедитесь, что диагностический print удален, а секции не дублируются.

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

Если форма не открывается, проверьте выбранные конфигурации и ошибки запроса MIGX. Если форма работает, но содержимое не выводится, проверьте обработку Fenom, значения MIGX_formname и чанки.

Следующий шаг

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

Дальше возвращаемся к учебному Creative и подключаем портфолио через Gallery. Сравним этот способ с уже подготовленным вариантом на MIGX.

Основные настройки и справочник находятся в основном уроке MIGX.

Настройка повторяемых полей и вложенных записей MIGX в MODX
← Предыдущая статьяMIGX в MODX: настройка полей и вывод данных
Следующая статья →Gallery в MODX: документация и практические примеры
Gallery в MODX: альбомы изображений и портфолио с фильтрами
Поделиться с друзьями
Алексей

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

Оцените автора
( 3 оценки, среднее 5 из 5 )
Web-Revenue.ru