PageBlocks 2.6.0. Настройка меню MODX и гибкое управление страницей пользователя

Создание пользовательских пунктов меню в MODX
В этой версии появилась возможность создавать собственные пункты меню прямо в админке MODX.
Рассмотрим пример добавления пункта меню «Отзывы» с выводом таблицы отзывов. (все картинки кликабельны)
Результат:

Инструкция по созданию
В режиме менеджера:
1.Создание таблицы для отзывов
- Перейдите в меню компонента
- Откройте вкладку «Таблицы»
- Создайте новую таблицу и добавьте необходимые поля:
- Добавьте колонки для отображения данных:


В режиме разработчика:
Добавляем код в файл core/App/Models/MainMenu.php
public function getMenu(): array
{
return [
// ... существующие пункты меню ...
Menu::make('reviews')
->title('Отзывы')
->description('Список отзывов')
->icon('fa-star')
->position(1)
->parent('components') // Размещаем в разделе компонентов
->fields([
// Добавляем поле с типом "таблица"
Field::make('reviews')
->label('Отзывы')
->type('table')
// Поля таблицы
->fields([
Field::make('name')
->label('Имя')
->required(),
Field::make('message')
->label('Отзыв')
->type('textarea')
->required(),
Field::make('date')
->label('Дата')
->type('date')
->storage('timestamp') // чтобы сохранялась дата в секундах
->dateFormat('Y-m-d, H:i')
->required()
->default(time()),
])
// настройка колонок
->columns([
Column::make('name')
->label('Имя')
->width(150),
Column::make('message')
->label('Отзыв'),
Column::make('date')
->label('Дата')
->width(150)
->render('date'),
])
// Добавляем поиск
->searchable()
]),
// ... другие пункты меню ...
];
}Выводим на сайт:
{'!pbTables'|snippet: [
'modelType' => 'pbMenu',
'field_name' => 'reviews', // имя поля таблицы
'tpl' => '@INLINE <figure class="text-center border pt-3">
<blockquote class="blockquote">
<p>{$message}</p>
</blockquote>
<figcaption class="blockquote-footer">
{$name}
{$date|date:"d-m-Y"}
</figcaption>
</figure>'
]}Расширенные возможности: несколько таблиц во вкладках
В рамках одного пункта меню можно организовать несколько таблиц с разными данными, используя вкладки.
Вот как это реализовать:
Пример создания меню с двумя вкладками:
Menu::make('feedback')
->title('Обратная связь')
->icon('fa-comments')
->parent('components')
->tabs([
// Первая вкладка с отзывами
Tab::make('Отзывы')
->fields([
Field::make('reviews_table')
->label('Список отзывов')
->type('table')
->fields([
Field::make('name')->label('Имя')->required(),
Field::make('message')->label('Текст')->type('textarea'),
Field::make('rating')->label('Оценка')->type('number')
])
->columns([
Column::make('name')->width(150),
Column::make('message'),
Column::make('rating')->width(80)
])
]),
// Вторая вкладка с заявками
Tab::make('Заявки')
->fields([
Field::make('requests_table')
->label('Заявки с формы')
->type('table')
->fields([
Field::make('phone')->label('Телефон')->required(),
Field::make('email')->label('Email'),
Field::make('created')->label('Дата')->type('date')
])
->columns([
Column::make('phone')->width(150),
Column::make('email'),
Column::make('created')->width(120)
])
])
]);Особенности реализации:
- Используем метод ->tabs() для создания вкладок
- Каждая вкладка (Tab::make()) содержит свою таблицу
- Таблицы полностью независимы друг от друга
- Можно настраивать разные наборы полей и колонок для каждой таблицы
- Количество вкладок не ограничено
Новые пункты отображаются в основном меню админ-панели:

Расширение профиля пользователя
Функционал полностью аналогичен работе с ресурсами. Все возможности, доступные для ресурсов, поддерживаются и для профилей пользователей.
1. Блоки
Режим менеджера
В панели пользователя всегда отображается вкладка PageBlocks (если не скрыта настройками).Доступные системные настройки для управления вкладкой:
- pageblocks_hide_users — список ID пользователей, для которых скрывается вкладка
- pageblocks_hide_user_groups — список групп пользователей, для которых скрывается вкладка
- pageblocks_tab_index — позиция вкладки (по умолчанию 0 — первая позиция)
Режим разработки
В этом режиме доступны только те блоки, которые явно указаны в модели пользователя (core/App/Models/User.php). Это обеспечивает полное разделение блоков для пользователей и ресурсов.Пример добавления блока в модель пользователя:
public static function getBlocks(): array
{
return [
Field::make('Образование') // Автоматическое имя чанка - 'obrazovanie'
->chunk('education') // Явное указание имени чанка
->fields([
Field::make('university')
->label('Университет')
->required(),
Field::make('degree')
->label('Степень')
->required(),
Field::make('date_start')
->label('Дата начала обучения')
->type('date')
->width(50)
->required(),
Field::make('date_end')
->label('Дата окончания обучения')
->type('date')
->width(50)
->required(),
])
];
}Результат в панели управления:

Вывод блоков на фронтенде
Используйте сниппет pbBlocks с указанием типа модели:{'!pbBlocks'|snippet: [
'modelType' => 'MODX\Revolution\modUser', // Для MODX2 указываем "modUser"
'user_id' => $modx->user->id, // ID пользователя
'fileElements' => 1, // Включение обработки файловых чанков
]}2. Вкладки
Добавление вкладки «Профессиональная информация»
Режим менеджера
- Перейдите на вкладку «Поля пользователя»
- Добавьте новую вкладку с нужными полями

Режим разработки
public static function getTabs(): array
{
return [
Tab::make('Профессиональная информация')
->fields([
Field::make('position')
->label('Должность')
->width(40),
Field::make('skills')
->label('Навыки')
->type('tag')
->width(40)
->options(['PHP', 'JavaScript', 'Дизайн', 'Маркетинг']),
Field::make('experience')
->label('Опыт работы (лет)')
->type('number')
->width(20)
->min(0)
->max(50)
])
];
}Результат

Вывод полей на фронтенде
// Вывод skills текущего пользователя
{$modx->user->skills}
// Вывод skills определенного пользователя
{1|user:'skills'}3. Панели
Режим менеджера
При добавлении вкладки поставьте галочку «Отдельная панель», чтобы вместо вкладки создать отдельную панель.Режим разработки
public static function getPanels(): array
{
return [
Panel::make('Социальные сети')
->position(0)
->fields([
Field::make('telegram')
->label('Telegram')
->prefix('@'),
Field::make('github')
->label('GitHub')
->prefix('https://github.com/')
->placeholder('username'),
Field::make('portfolio')
->label('Портфолио')
->placeholder('URL'),
])
];
}Результат:

Вывод на фронтенде осуществляется так же, как и для полей из вкладок.
Заключение
Расширение профиля пользователя с помощью блоков, вкладок и панелей позволяет гибко настраивать дополнительные поля и структуру данных, сохраняя при этом единый подход к работе с контентом — как для ресурсов, так и для пользователей.
PageBlocks активно развивается — это только начало! Уже реализовано много крутых фич, но впереди ещё масса идей и улучшений. Я продолжаю работать над тем, чтобы PageBlocks стал ещё более удобным и мощным инструментом для разработчиков на MODX.
Не стесняйтесь делиться своими идеями и пожеланиями — они всегда будут учтены!
В статье перечислены не все нововведения и возможности этой версии. О них вы узнаете в следующих уроках.
Комментарии: 16
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Автору — спасибо! Будем пробовать при случае!
Во-вторых, настройка таблиц в PageBlocks куда мощнее: данные сохраняются не в JSON, а в нормальной структуре БД, что даёт гибкость для фильтрации, поиска и реализации сложной логики.
А ещё в PageBlocks есть блоки, синхронизация блоков между ресурсами, встроенный роутинг и многое другое.
Поэтому PageBlocks на порядок мощнее MIGX — это уже полноценный фреймворк внутри MODX.
Так-то программирование в чанках с начала времён (появления php-шаблонизаторов) считалось плохой идеей, но MIGX так располагает, что про это многие забыли. Просто fenom даёт слишком много свободы, а MOGX как бы располагал к тому, чтобы этой свободой злоупотреблять…
Так что ты, @Aleksandr Huz тот самый наш герой, который показывает, что мир может быть другим, и код — красивым!
Вы вообще видели этот синтаксис в примерах «Режим разработки» из поста? Анбиливабл эвесамнесс какой-то! Слов нет как круто...
В компонент уже встроена экспериментальная функция AI Block, которая позволяет на основе верстки автоматически создать конструктор блока, чанк и сразу добавить заполненный блок на текущую страницу — без каких-либо дополнительных атрибутов в верстке.
К сожалению, со сложными блоками ChatGPT справляется плохо, поэтому я пока отложил этот функционал.
Для включения этой функции нужно добавить ключ в настройку pageblocks_chatgpt_apikey и после этого в меню настроек блоков (рядом с кнопкой «Создать») добавить соответствующий пункт.
По сути, добавлять атрибуты в вёрстку — это то же самое, что вручную расставлять плейсхолдеры. Только ещё нужно знать, какие атрибуты использовать и куда их вставлять, поэтому этот вариант пока не рассматривается.
Сейчас в приоритете — режим разработчика и роутинг.
совы на глобусверстки нужно расставить плейсхолдеры и записать значение плейсхолдера в админке. А перед этим нужно создать поля для этих значений. А тут ты расставил атрибуты, запустил скрипт и плейсхолдеры расставились, поля создались, значения записались. Другое дело, что migx не лучший способ хранения данных, поэтому твой подход безусловно круче.Как работает мультиязычность? Допустим я перевел блок на три языка, как на фронте переключить язык?
Скоро будет отдельная статья про мультиязычность.
Создал по вашему примеру через режим разработчика «Пример создания меню с двумя вкладками»
Всё появилось отлично, но если я например хочу туда добавить простое текстовое поле
То оно не появляется.
В журнале ошибок показывает
/core/src/Revolution/modMenu.php 80
The menu cache key menus/ru could not be written.
Версия Modx 3.1.2
php 8.2
Разрешено добавлять только таблицы, ведь простые поля не будут сохраняться, там нет этого функционала.
Я думал там есть такая возможность.
Тогда вопрос отпал.