n1ce2k / nexor-pagebuilder
Модуль «Конструктор страниц» для NEXOR CMS: детальная страница элемента из блоков.
Requires
- php: ^8.3
- ext-dom: *
- n1ce2k/nexor-cms: ^0.2
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-17 15:19:12 UTC
README
Модуль для NEXOR CMS: детальная страница элемента собирается из блоков вместо подробного текста. Доступен на всех лицензиях.
composer require n1ce2k/nexor-pagebuilder php artisan nexor-pagebuilder:install
Установщик создаёт таблицу pagebuilder_layouts. Редактор в панели приходит собранным в dist/, стили и скрипт блоков для сайта — в resources/assets/.
Как пользоваться
- Инфоблок → «Параметры» → «Использовать конструктор детальной страницы».
- У элементов появится вкладка «Конструктор»: блоки перетаскиваются из палитры слева или добавляются кликом, меняются местами, сворачиваются, дублируются.
- Блоки сохраняются вместе с элементом кнопкой «Сохранить».
- На сайте, пока у элемента есть блоки, они выводятся вместо подробного текста. Нет блоков или переключатель снят — снова подробный текст, а сами блоки остаются в базе.
Выключить модуль целиком можно на странице «Модули»: вкладка и вывод пропадут, данные останутся.
Блоки первой версии
Вёрстка блоков — классы pb-* и nw-*, как в исходном конструкторе: pb-wrapper → pb-content → pb-block-wrapper[data-type] → section.pb-block.pb-<тип> → pb-container. Стили, написанные под эти классы, подходят без изменений.
| Тип | Блок | Данные |
|---|---|---|
header |
Заголовок | text, tag (h2–h5) |
text |
Текст | text, text2, cols (1 или 2 колонки — is-col-2) |
quote |
Цитата | text, showAuthor, author, role, avatar |
text_image |
Текст + Фото | text, image, imagePosition (left/right — pb-text-image--right) |
photo |
Фото / Галерея | images [{path, alt, title}], layoutMode (preset/custom), presetId (1, 2, 3, 4, 4_grid, 3_asym), asymmetricDir, customCols, customVisible, showOverlay («+N») |
slider |
Слайдер | images [{path, alt, title}], slidesPerView (1–6), gap, autoplay, arrows, dots |
video |
Видео | sourceType (link/file), url или file + poster, layout (full/caption/split), reverse, text, settings {autoplay, loop, muted, controls} |
accordion |
Аккордеон | items [{title, content}], openFirst; разметка schema.org FAQPage |
tabs |
Табы | items [{id, title, content}], activeTabId — какая вкладка открыта |
table |
Таблица | rows [[ячейка, …]], header (первый ряд из <th>), showTitle, title, titleTag |
catalog_list |
Каталог | title, description, cardTemplate, source {iblockId, selectionMode (section/all/manual), sectionId, manualItems [{id, name}], sortBy (sort/active_from/name), limit}, view {slidesPerView, gap, arrows, dots} |
link_cards |
Ссылки / Файлы | description, variant (apps — текст и картинка, docs — документы), cols (1–4), items [{text, link, file, image, isDownload}] |
У каждого блока есть cssClass — дополнительный класс секции. У всей раскладки — боковое меню pb-aside со ссылками на блоки (settings.showSidebar, settings.sidebarItems).
Файлы (image, avatar, file, poster, images[], файлы и картинки карточек) хранятся путём в хранилище; шаблон получает { src, alt, title }.
HTML из визуального редактора чистится при сохранении по белому списку: без скриптов, стилей, обработчиков и javascript:-ссылок. Видео встраивается только по адресу плеера, собранному из распознанной ссылки. Файлы загружает тот, у кого есть право менять элементы инфоблока: картинки jpg, png, webp, gif, видео mp4, webm и документы (pdf, doc(x), xls(x), ppt(x), odt, ods, rtf, txt, csv, zip, rar, 7z) — тип документа проверяется по содержимому.
Стили и скрипт на сайте
Вместе с блоками выводятся pagebuilder.css и pagebuilder.js модуля (адрес /nexor-pagebuilder/assets/…, один раз на страницу):
- оформление классов
pb-*иnw-*; цвета берутся из переменных темы сайта (--color-blue-600и т. п.), без них — запасные; - аккордеон (
data-accordion), табы (data-tabs), плавная прокрутка оглавления; - Fancybox для фото (
data-fancybox) и Swiper для «Слайдера» и «Каталога» — если сайт их подключил.
Swiper модуль не везёт — его подключает сайт (в макете, до конца <body>). Скрипт модуля находит window.Swiper и оживляет все .js-pb-slider; сборка без модулей может передать их через window.SwiperModules. Без Swiper карусели показываются обычной сеткой.
Карточка в «Каталоге» задаётся полем «Шаблон карточки» — именем шаблона компонента после nexor::components.. Пусто — стандартная catalog.card.default: с ценой, а кнопка «В корзину» стоит внутри @feature('shop') и появляется, только если модуль «Магазин» установлен и включён.
Своя карточка:
php artisan nexor:component catalog.card mini— появитсяresources/views/vendor/nexor/components/catalog/card/mini.blade.php(внутри доступна$element);- сверстать его;
- в блоке вписать
catalog.card.mini.
Имя проверяется при сохранении (такой шаблон должен существовать); если шаблон потом удалили — на сайте стандартная карточка. Поле подсказывает уже созданные шаблоны из components/*/card/. Показываются только опубликованные элементы активного инфоблока; раздел берётся вместе с подразделами, ручной выбор сохраняет порядок.
Свои стили вместо модульных — NEXOR_PAGEBUILDER_ASSETS=false или PageBuilder::render($element, ['assets' => false]). Тогда обёртка получает data-pb-standalone="false", и скрипт модуля её не трогает.
Вывод на сайте
В стандартных шаблонах catalog.element, news.detail и site/page уже есть:
@feature('pagebuilder') @php($pageBuilder = \Nexor\PageBuilder\PageBuilder::render($element)->toHtml()) @endfeature @if (! empty($pageBuilder)) {!! $pageBuilder !!} @else {{-- подробный текст --}} @endif
Свой шаблон элемента — вставьте этот кусок туда, где должен быть контент.
Шаблоны блоков забираются к себе и верстаются как угодно:
php artisan nexor-pagebuilder:component # список php artisan nexor-pagebuilder:component text # один блок php artisan nexor-pagebuilder:component all # все блоки и обёртка
Копии лежат в resources/views/vendor/nexor-pagebuilder и обновлением модуля не перезаписываются.
Свой блок
use Nexor\PageBuilder\Blocks\Block; use Nexor\PageBuilder\PageBuilder; class PromoBlock extends Block { public function type(): string { return 'promo'; } public function label(): string { return 'Промо'; } public function rules(): array { return ['title' => ['nullable', 'string', 'max:255']]; } public function view(): string { return 'blocks.promo'; } } // в AppServiceProvider::boot() PageBuilder::blocks()->register(new PromoBlock);
Редактор блока в панели — Vue-компонент с prop data (правится на месте):
window.Nexor.pageBuilder.registerEditor('promo', PromoEditor);
Как устроено
- Раскладка — JSON-документ
{ version, settings, blocks: [{ id, type, data }] }в таблицеpagebuilder_layouts. Владелец описан паройowner_type+owner_id, поверхность —surface. - Модуль встраивается в ядро через точки расширения
Module::iblockSettings(),elementFields(),elementRules(),elementValues(),saveElement()— ядро не знает про конструктор. - В панели поле формы регистрируется через
Nexor.registerFormField('pagebuilder.content', …).
Дальше: конструктор страниц сайта
Следующий большой этап — страницы целиком, как в шаблонах Аспро: главная и лендинги собираются из секций в админке. Задел уже заложен:
Surface::Page— вторая поверхность; блок объявляет, где он доступен (Block::surfaces()).pagebuilder_layoutsрассчитана на других владельцев: страница будетowner_type = page.settingsв документе раскладки — под параметры всей страницы.
Что предстоит продумать и сделать:
- Сущность «Страница»: адрес, SEO, макет, публикация; раздел «Страницы» в панели и маршрут на сайте (fallback, как у инфоблоков).
- Секции страницы: ширина (контейнер / во всю ширину), фон, отступы, видимость на мобильных — в
settingsкаждого блока. - Блоки-витрины, привязанные к инфоблокам: «Товары из раздела», «Новости», «Баннеры», «Преимущества», «Отзывы», «Бренды» — через
InfoBlockService, с выбором инфоблока, раздела, количества и шаблона карточки. - Шаблоны секций: несколько вариантов вёрстки одного блока (как «типы» блоков в Аспро) и превью варианта в палитре.
- Предпросмотр страницы в панели до публикации и черновики.
- Блоки второй очереди готовы: слайдер, табы, ссылки/файлы, каталог. Дальше — фильтр каталога по свойствам и «Товары из текущего раздела» для детальной страницы.
- Поиск: подключить
pagebuilder_layouts.search_textк поиску ядра (нужна точка расширения вInfoBlockService::searchElements). - Уборка файлов: удалять загруженные картинки, на которые больше не ссылается ни одна раскладка.