Панели и Блоки: техническое руководство для разработчиков
Эта статья описывает архитектуру системы «Панели и Блоки» на техническом уровне: структуру таблиц, поля, шаблоны и возможности расширения.
Целевая аудитория: разработчики, которые настраивают и расширяют функционал платформы.
Архитектура системы
Система «Панели и Блоки» состоит из трёх основных компонентов:
- Таблицы БД —
s_Panels(панели) иs_Blocks(блоки) - PHP-логика — класс
BlocksвWeppsExtensions/Template/Blocks/ - Шаблоны —
.tplфайлы для рендеринга панелей
Как это работает
// packages/WeppsExtensions/Template/Blocks/Blocks.php
$obj = new Data("s_Panels");
$panels = $obj->fetch("t.IsHidden=0 and t.NavigatorId='{$this->navigator->content['Id']}'");
// Для каждой панели загружаются её блоки
$obj = new Data("s_Blocks");
$blocks = $obj->fetch("t.IsHidden=0 and p.NavigatorId='{$navigatorId}'");
// Панель рендерится через свой Template или стандартный Blocks.tpl
if (empty($panel['Template'])) {
// Стандартный шаблон
$tpl = 'packages/WeppsExtensions/Template/Blocks/Blocks.tpl';
} else {
// Кастомный шаблон панели (например, AccordionPanel)
$extensionClass = "\WeppsExtensions\Template\Blocks\{$panel['Template']}\{$panel['Template']}";
$extension = new $extensionClass($this->navigator, $this->headers);
}
Таблица s_Panels — конфигурация панелей
Панель — это контейнер для блоков. Она определяет:
- Куда вставляется (привязка к странице через
NavigatorId) - Как располагаются блоки внутри (через
LayoutCSS) - Какой шаблон использовать для рендеринга (через
Template)
Основные поля
| Поле | Тип | Описание |
|---|---|---|
Id |
INT PRIMARY KEY | Уникальный идентификатор панели |
NavigatorId |
INT | ID страницы из s_Navigator, к которой привязана панель |
Name |
VARCHAR(255) | Название панели (может выводиться в шаблоне как заголовок) |
Descr |
TEXT | Описание панели (подзаголовок или вводный текст) |
Template |
VARCHAR(128) | Имя кастомного шаблона панели (например, AccordionPanel) |
LayoutCSS |
VARCHAR(255) | CSS-классы для контейнера блоков (например, w_grid w_3col) |
IsHidden |
INT | Видимость панели (0=показана, 1=скрыта) |
Priority |
INT | Порядок сортировки (чем меньше число, тем выше панель) |
Images |
INT | Количество изображений (стандартное поле для файлов) |
Files |
INT | Количество файлов (стандартное поле для файлов) |
Ключевое поле: LayoutCSS
Это поле определяет, как блоки располагаются внутри панели. Используются встроенные CSS-классы платформы:
Сетка (Grid)
w_grid w_2col /* 2 колонки */
w_grid w_3col /* 3 колонки */
w_grid w_4col /* 4 колонки */
Flexbox (строка)
w_flex w_flex_row w_flex_margin /* Блоки в ряд с отступами */
Flexbox (столбик)
w_flex w_flex_col /* Блоки друг под другом */
Пример:
INSERT INTO s_Panels (NavigatorId, Name, LayoutCSS, Priority) VALUES
(5, 'Наши услуги', 'w_grid w_3col', 1);
Результат: блоки внутри этой панели автоматически выстроятся в сетку 3 колонки.
Таблица s_Blocks — контент блоков
Блок — это конкретный элемент с контентом внутри панели.
Основные поля
| Поле | Тип | Описание |
|---|---|---|
Id |
INT PRIMARY KEY | Уникальный идентификатор блока |
PanelId |
INT | ID панели из s_Panels, к которой привязан блок |
Name |
VARCHAR(255) | Название блока (обычно заголовок) |
Descr |
TEXT | Описание блока (основной текст) |
Template |
VARCHAR(128) | Кастомный шаблон блока (опционально) |
LayoutCSS |
VARCHAR(255) | Индивидуальные CSS-классы для блока |
IsHidden |
INT | Видимость блока (0=показан, 1=скрыт) |
Priority |
INT | Порядок сортировки внутри панели |
Images |
INT | Количество изображений |
Files |
INT | Количество файлов |
Ключевое поле: LayoutCSS
Индивидуальные стили для конкретного блока. Обычно используется редко, так как общий стиль задаётся на уровне панели.
Примеры использования:
- Выделить один блок цветом:
w_shadow(добавляет тень) - Изменить ширину блока в сетке:
w_2scol(занять 2 колонки в grid)
Пример:
INSERT INTO s_Blocks (PanelId, Name, Descr, Priority) VALUES
(1, 'Быстрая доставка', 'Доставим в течение 24 часов', 1);
Шаблоны панелей
Стандартный шаблон: Blocks.tpl
Если поле Template в таблице s_Panels пустое, используется стандартный шаблон:
{* packages/WeppsExtensions/Template/Blocks/Blocks.tpl *}
<div class="w_panel blockstest" id="w_panel_{$panel.Id}">
{$content.Id|wepps:'panels':$panel.Id}
<div class="wrapper">
<div class="w_blocks{if $user.ShowAdmin} w_sortable{/if} {$panel.LayoutCSS}">
{foreach name="blocks" item="block" from=$blocks}
<div class="w_block blockstest {$block.LayoutCSS}"
id="w_block_{$panel.Id}_{$block.Id}"
data-id="{$block.Id}">
{$block.Id|wepps:'s_Blocks'}
{$block.Name}
{$block.Template}
</div>
{/foreach}
</div>
</div>
</div>
Обратите внимание:
{$panel.LayoutCSS}— применяется к контейнеру блоков{$block.LayoutCSS}— применяется к каждому блоку{if $user.ShowAdmin} w_sortable{/if}— включает drag-n-drop для авторизованных администраторов
Кастомные шаблоны панелей
Вы можете создать собственный шаблон панели для особых случаев (аккордеон, табы, слайдер и т.д.).
Пример: AccordionPanel
Структура:
WeppsExtensions/Template/Blocks/AccordionPanel/
├── AccordionPanel.php # Класс-обработчик
├── AccordionPanel.tpl # Шаблон
├── AccordionPanel.css # Стили
└── AccordionPanel.js # Логика (раскрытие/скрытие)
PHP-класс:
<?php
namespace WeppsExtensions\Template\Blocks\AccordionPanel;
use WeppsCore\Extension;
use WeppsCore\Smarty;
class AccordionPanel extends Extension {
public function request() {
$smarty = Smarty::getSmarty();
$this->tpl = $smarty->fetch('packages/WeppsExtensions/Template/Blocks/AccordionPanel/AccordionPanel.tpl');
$this->headers->css("/ext/Template/Blocks/AccordionPanel/AccordionPanel.{$this->rand}.css");
$this->headers->js("/ext/Template/Blocks/AccordionPanel/AccordionPanel.{$this->rand}.js");
}
}
Шаблон:
<div class="page w_panel panel-accordion" id="w_panel_{$panel.Id}">
{$content.Id|wepps:'panels':$panel.Id}
<section class="panel-accordion-header">
{if $panel.Name}
<div class="title">{$panel.Name}</div>
{/if}
{if $panel.Descr}
<div class="text">{$panel.Descr}</div>
{/if}
{if $panel.Images_FileUrl}
<div class="img">
<img src="{$panel.Images_FileUrl}"/>
</div>
{/if}
</section>
<section class="panel-accordion-wrapper">
<div class="w_blocks {if $user.ShowAdmin} w_sortable{/if} {$panel.LayoutCSS}">
{foreach name="blocks" item="block" from=$blocks}
<div class="w_block block-accordion {$block.LayoutCSS}"
id="w_block_{$panel.Id}_{$block.Id}"
data-id="{$block.Id}">
{$block.Id|wepps:'s_Blocks'}
<div class="title">{$block.Name}</div>
<div class="text w_hide">{$block.Descr}</div>
</div>
{/foreach}
</div>
</section>
</div>
Использование:
В админке, в списке s_Panels, установите поле Template = AccordionPanel.
Добавление кастомных полей
Система гибкая — вы можете добавлять свои поля в таблицы s_Panels и s_Blocks исключительно через административную панель, используя стандартный механизм s_ConfigFields.
⚠️ Важно: Никогда не используйте прямые SQL-запросы типа ALTER TABLE для добавления полей! Платформа автоматически создаёт столбцы в БД при добавлении записи в список "Настройки полей" s_ConfigFields.
Пример: добавить поле BackgroundColor в панели
Через интерфейс админки:
-
Откройте настройки полей:
- Перейдите в
/_wepps/ - Настройки → Настройки полей (
s_ConfigFields)
- Перейдите в
-
Добавьте новое поле:
- Нажмите "Добавить элемент"
- Заполните форму:
TableName: s_Panels Field: BackgroundColor Name: Цвет фона Type: color Required: 0 Priority: 50 IsHidden: 0 - Нажмите "Сохранить"
-
Готово! Платформа автоматически:
- Создаст столбец
BackgroundColorв таблицеs_Panels - Добавит поле в форму редактирования панели
- Тип
colorсоздаст HTML5 colorpicker
- Создаст столбец
Альтернатива: массовое добавление через Excel
Если нужно добавить сразу несколько полей, используйте загрузку из Excel-файла:
- Создайте файл
.xlsxс колонками:Список,Наименование,Alias,Тип,Группа,Описание - Заполните строку:
s_Panels | Цвет фона | BackgroundColor | color | FieldDefault | Цвет фона панели - В админке: Настройки → Настройки полей → Загрузить из Excel
- Выберите файл и загрузите
Подробнее о загрузке через Excel: см. Добавление полей в список → раздел "Способ 2: Загрузка полей из Excel"
- Используйте в шаблоне:
<div class="w_panel" style="background-color: {$panel.BackgroundColor}"> ... </div>
Доступные типы полей:
text— текстовое полеarea— текстовая область (textarea)color— colorpicker (HTML5)select::TableName— выпадающий список из другой таблицыflag— checkbox (0/1)int— целое числоdigit— число с плавающей точкойdate— датаfile— загрузка файла
Подробнее: см. статью Добавление полей в список
Лучшие практики
1. Используйте LayoutCSS вместо инлайн-стилей
❌ Плохо:
UPDATE s_Panels SET Name = '<div style="display: grid">...</div>' WHERE Id = 1;
✅ Хорошо:
UPDATE s_Panels SET LayoutCSS = 'w_grid w_3col' WHERE Id = 1;
2. Создавайте кастомные шаблоны для сложной логики
Если блокам нужна интерактивность (табы, аккордеоны, слайдеры) — создавайте отдельный шаблон панели.
3. Не дублируйте контент в Name и Descr
Эти поля предназначены для разных целей:
Name— краткий заголовок (1-3 слова)Descr— развёрнутое описание или текст
4. Используйте Priority для управления порядком
Панели и блоки сортируются по полю Priority (меньше = выше). Оставляйте «запас» между значениями (10, 20, 30), чтобы можно было вставить элемент между ними.
5. Группируйте блоки логически
Одна панель = одна логическая секция страницы. Не смешивайте в одной панели разнородный контент.
Примеры использования
Важное примечание: Все примеры ниже показаны через SQL-запросы для наглядности структуры данных. На практике создание и редактирование панелей и блоков выполняется через административную панель в списках
s_Panelsиs_Blocks. SQL-запросы используются только для массовых операций, миграций или автоматизации через скрипты.
Пример 1: Секция «Наши преимущества» (сетка 3 колонки)
Через админку:
- Откройте Списки данных → Панели (
s_Panels) - Создайте панель:
NavigatorId: выберите нужную страницуName:Наши преимуществаLayoutCSS:w_grid w_3colPriority:10
- Сохраните панель
- Откройте Списки данных → Блоки (
s_Blocks) - Создайте три блока с полем
PanelId= ID созданной панели:- Блок 1:
Name=Быстро,Descr=Доставка за 24 часа,Priority=1 - Блок 2:
Name=Надёжно,Descr=Гарантия 2 года,Priority=2 - Блок 3:
Name=Выгодно,Descr=Скидка до 30%,Priority=3
- Блок 1:
SQL-эквивалент (для понимания структуры):
INSERT INTO s_Panels (NavigatorId, Name, LayoutCSS, Priority) VALUES
(5, 'Наши преимущества', 'w_grid w_3col', 10);
INSERT INTO s_Blocks (PanelId, Name, Descr, Priority) VALUES
(1, 'Быстро', 'Доставка за 24 часа', 1),
(1, 'Надёжно', 'Гарантия 2 года', 2),
(1, 'Выгодно', 'Скидка до 30%', 3);
Результат: 3 карточки преимуществ в ряд.
Пример 2: Секция FAQ (аккордеон)
Через админку:
- Откройте Списки данных → Панели
- Создайте панель:
NavigatorId: страница FAQName:Часто задаваемые вопросыTemplate:AccordionPanel(выбрать из списка)Priority:20
- Откройте Списки данных → Блоки
- Создайте блоки для вопросов/ответов:
- Блок 1:
Name=Как оформить заказ?,Descr=Добавьте товары в корзину и заполните форму. - Блок 2:
Name=Какие способы оплаты?,Descr=Мы принимаем карты, наличные и банковские переводы.
- Блок 1:
SQL-эквивалент:
INSERT INTO s_Panels (NavigatorId, Name, Template, Priority) VALUES
(7, 'Часто задаваемые вопросы', 'AccordionPanel', 20);
INSERT INTO s_Blocks (PanelId, Name, Descr, Priority) VALUES
(2, 'Как оформить заказ?', 'Добавьте товары в корзину и заполните форму.', 1),
(2Через админку:**
1. Откройте **Списки данных** → **Панели**
2. Создайте панель:
- `LayoutCSS`: `w_flex w_flex_row w_flex_margin`
- `Priority`: `30`
3. Откройте **Списки данных** → **Блоки**
4. Создайте блоки с разной шириной:
- Блок 1: `Name` = `Главный блок`, `LayoutCSS` = `w_flex_23` (займёт 2/3 ширины)
- Блок 2: `Name` = `Боковой блок`, `LayoutCSS` = `w_flex_13` (займёт 1/3 ширины)
**SQL-эквивалент:**
```sql
INSERT INTO s_Panels (NavigatorId, LayoutCSS, Priority) VALUES
(8, 'w_flex w_flex_row w_flex_margin', 30);
INSERT INTO s_Blocks (PanelId, Name, LayoutCSS, Priority) VALUES
(3, 'Главный блок', 'w_flex_23', 1), -- Занимает 2/3 ширины
(3, 'Боковой блок', 'w_flex_13', 2); -- Занимает 1/3 ширины
Результат: Два блока в одной строке с разной шириной (2:1).ERT INTO s_Panels (NavigatorId, LayoutCSS, Priority) VALUES (8, 'w_flex w_flex_row w_flex_margin', 30);
**Создание блоков с разной шириной:**
```sql
INSERT INTO s_Blocks (PanelId, Name, LayoutCSS, Priority) VALUES
(3, 'Главный блок', 'w_flex_23', 1), -- Занимает 2/3 ширины
(3, 'Боковой блок', 'w_flex_13', 2); -- Занимает 1/3 ширины
Отладка и диагностика
Как посмотреть, какие панели загружены?
В режиме разработки ('debug' => 1 в config.php):
use WeppsCore\Utils;
// Добавьте в Blocks.php
Utils::debug($panels); // Выведет все панели для текущей страницы
Как проверить, что блоки привязаны правильно?
SELECT
p.Name AS PanelName,
b.Name AS BlockName,
b.Priority
FROM s_Blocks b
JOIN s_Panels p ON p.Id = b.PanelId
WHERE p.NavigatorId = 5
ORDER BY p.Priority, b.Priority;
Частые ошибки
1. Панель не отображается
- Проверьте
IsHidden = 0 - Убедитесь, что
NavigatorIdсоответствует нужной странице - В административной панели откройте нужный раздел в Навигаторе и убедитесь, что тумблер «Использовать Блоки» включен
2. Блоки не выстраиваются в сетку
- Проверьте
LayoutCSSвs_Panels— должен бытьw_grid w_Ncol - Убедитесь, что CSS-файлы подключены
3. Drag-n-drop не работает
- Убедитесь, что вы авторизованы в админке
- Проверьте, что в шаблоне есть класс
w_sortable
Заключение
Система «Панели и Блоки» — это мощный инструмент для создания гибких страниц:
- Панели определяют структуру и расположение
- Блоки наполняют контентом
- Шаблоны управляют рендерингом
- LayoutCSS даёт визуальный контроль без написания кода
Комбинируя эти элементы, вы можете создавать от простых секций до сложных интерактивных компонентов.
Дополнительные материалы:
- Концепция «Панели и Блоки» — для понимания идеи
- Руководство администратора — для работы с контентом
- Flexbox CSS — документация по классам расположения
- Grid CSS — документация по сеточным классам