Add "Blocks"
153
Blocks.md
Normal file
153
Blocks.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Блоки и шаблоны
|
||||
|
||||
## Что такое блок
|
||||
|
||||
Блок — единица конструктора. Каждый блок = фрагмент Pug-кода, который при сборке конкатенируется с другими блоками в итоговый PUG-файл.
|
||||
|
||||
Блоки хранятся в `Block.pug` (файл `z51-pug-builder/public/Block.pug`), разделены комментариями `//Название блока`.
|
||||
|
||||
## Как парсятся блоки
|
||||
|
||||
Файл `parsing.js` → функция `parseBlocks(text)`:
|
||||
1. Разбивает текст по строкам, начинающимся с `//`
|
||||
2. Каждый `//` — начало нового блока, текст после `//` — имя
|
||||
3. Содержимое до следующего `//` — контент блока
|
||||
4. Блоки с именем "Доп. текст" фильтруются
|
||||
|
||||
Результат: `[{name: "Заголовок", content: "+spacerLine(40)\ntr\n td..."}, ...]`
|
||||
|
||||
## Типы полей
|
||||
|
||||
При добавлении блока в конструктор, система строит **схему полей** (`buildBaseSchema`):
|
||||
|
||||
| Тип поля | Описание | Пример в Pug |
|
||||
|----------|----------|-------------|
|
||||
| `raw` | Весь контент блока как есть | Блоки "3 товара в ряд" |
|
||||
| `text` | Текстовое содержимое после тега | `span.font.h2 ТЕКСТ` |
|
||||
| `mixin-text` | Текстовый аргумент миксина | `+buttonRounded("Текст", ...)` |
|
||||
| `mixin-href` | URL-аргумент миксина | `+buttonRounded("...", "https://...")` |
|
||||
| `mixin-ids` | Список ID (через запятую) | `+products4("123,456,789")` |
|
||||
| `mixin-opts` | Объект опций в миксине | `+products4("...", {hidePrice: true})` |
|
||||
| `href` | Атрибут href | `a(href="https://...")` |
|
||||
| `src` | Атрибут src | `img(src="https://...")` |
|
||||
| `list-item` | Элемент списка (tr+td+span) | Блоки с таблицами товаров |
|
||||
|
||||
## Автоопределение полей
|
||||
|
||||
Функция `guessAutoMixinField(rawArg, argIndex)` определяет тип аргумента миксина:
|
||||
- Содержит запятые и цифры → `mixin-ids`
|
||||
- Начинается с `{` → объект, парсится `parseMixinObjectArg`
|
||||
- Начинается с `http`/`/` → `mixin-href`
|
||||
- Иначе → `mixin-text`
|
||||
|
||||
Для объектных аргументов (`{key: value}`) каждый ключ проверяется через `shouldExposeObjectField`:
|
||||
- Пропускаются служебные: `class`, `style`, `id`, `data-*`
|
||||
- Тип определяется по имени ключа (`guessObjectFieldByKey`): `url`/`href`/`link` → href, `src`/`image`/`img` → src, иначе → text
|
||||
|
||||
## Секции блока
|
||||
|
||||
Сложные блоки (карточки товаров) состоят из **секций** — повторяющихся групп строк внутри `tr`:
|
||||
|
||||
```pug
|
||||
tr ← колонка
|
||||
td.paddingWrapper
|
||||
+defaultTable("100%")
|
||||
tr ← секция "Картинка"
|
||||
td
|
||||
img(src="...")
|
||||
+spacerLine(10)
|
||||
tr ← секция "Текст"
|
||||
td
|
||||
span.font ТЕКСТ
|
||||
```
|
||||
|
||||
Функция `parseSections(content)` находит такие структуры и позволяет:
|
||||
- **Перемещать секции** вверх/вниз внутри блока (`moveSectionInBlock`)
|
||||
- **Удалять секции** с автоудалением спейсеров (`removeSectionFromBlock`)
|
||||
|
||||
Типы секций определяются по содержимому (`guessSectionLabel`): Кнопка, Картинка, Товары, Заголовок, Текст, Ссылка.
|
||||
|
||||
## Product Options
|
||||
|
||||
Для блоков с товарами (миксины `+products*`) есть **опции** — ключи в объектном аргументе:
|
||||
|
||||
```pug
|
||||
+products4("123,456,789", {hidePrice: true, showOldPrice: false})
|
||||
```
|
||||
|
||||
Опции настраиваются в settings.json → `productOptions[]`:
|
||||
```json
|
||||
[
|
||||
{"key": "hidePrice", "label": "Скрыть цену", "default": false},
|
||||
{"key": "showOldPrice", "label": "Показать старую цену", "default": true}
|
||||
]
|
||||
```
|
||||
|
||||
Кнопки в UI: включить/выключить опцию для одного блока или всех блоков.
|
||||
|
||||
## Mixin Rules
|
||||
|
||||
Правила разметки аргументов миксинов (когда автоопределение не справляется):
|
||||
|
||||
```json
|
||||
{
|
||||
"mixin": "+products4",
|
||||
"args": [
|
||||
{"index": 0, "type": "mixin-ids", "label": "ID товаров"},
|
||||
{"index": 1, "type": "mixin-opts", "label": "Опции"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Кастомные блоки
|
||||
|
||||
Пользователь может:
|
||||
1. **Дублировать** существующий блок как кастомный (`duplicateBlockAsCustom`)
|
||||
2. **Создать** новый в настройках (`addCustomBlock`)
|
||||
3. **Переименовать** блок (`renameBlock`)
|
||||
|
||||
Кастомные блоки хранятся в `settings.customBlocks[]` и мержатся с блоками из Block.pug.
|
||||
|
||||
## Quick Blocks
|
||||
|
||||
Быстрые блоки — панель кнопок над списком блоков для быстрого добавления:
|
||||
- Настраиваются в settings → `quickBlocks[]`
|
||||
- Поддерживают drag-and-drop для перестановки
|
||||
- 3 цвета: White (default), Blue, Green → `quickBlockColors`
|
||||
|
||||
## Шаблоны блоков
|
||||
|
||||
Каждый блок может иметь **переопределённый шаблон** в settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"blocks": {
|
||||
"БАННЕР": {
|
||||
"template": "+spacerLine(40)\ntr\n td\n a(href=\"\")\n img(src=\"\")",
|
||||
"defaultSpacing": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`getEffectiveTemplate(name)` — возвращает override из settings или оригинал из Block.pug.
|
||||
|
||||
## Спейсеры между блоками
|
||||
|
||||
- `globalSpacing` — отступ по умолчанию (обычно 40)
|
||||
- Каждый блок может переопределить: `block.spacing` (ввод в UI) или `settings.blocks[name].defaultSpacing`
|
||||
- `block.addSpacing` — флаг, добавлять ли спейсер перед блоком
|
||||
- При сборке: `+spacerLine(spacing)` вставляется между блоками
|
||||
|
||||
## Drag-and-Drop блоков
|
||||
|
||||
Блоки в конструкторе перетаскиваются мышью:
|
||||
- `handleBlockDragStart(index)` → `handleBlockDragOver(index)` → `handleBlockDrop(index)`
|
||||
- Визуальная индикация: `dragging-block`, `drag-over-block`
|
||||
- Обновляет массив `assembledBlocks[]`
|
||||
|
||||
## Import/Export
|
||||
|
||||
- `exportBlocksPug()` — экспорт всех шаблонов блоков в текст
|
||||
- `importBlocksPug()` — импорт из текста (парсит и обновляет block.pug)
|
||||
- `downloadBlocksPug()` — скачивание как файл
|
||||
Reference in New Issue
Block a user