Skip to content
ФреймворкJavaScript

Всё является блоком: модель данных Blok

У Blok одна основная идея. Поймите её — и остальной API сложится сам собой.

Обновлено 30 июн. 2026 г.Редактировать на GitHub

В Blok любая часть контента — это блок. Рядом с блоками не существует отдельной модели документа: блок — это универсальный примитив. Абзац — блок. Заголовок — блок. Целая база данных и каждая строка в ней — тоже блоки. Как только это укладывается в голове, API перестаёт выглядеть списком возможностей и начинает читаться как одно цельное дерево.

Форма блока

Каждый блок — какого бы он ни был типа — это один и тот же небольшой объект. type указывает инструмент, который его отображает, data хранит содержимое этого инструмента, а tunes — необязательные настройки уровня блока.

TypeScript
// Every block — whatever its type — is the same small object
{
  id: 'block-a1b2c3',              // unique, auto-generated
  type: 'paragraph',              // which tool renders it
  data: { text: 'Hello, world' }, // the tool's content
  tunes: {},                      // block-level settings (optional)
}

Блоки образуют дерево

Блоки — не плоский список. Любой блок может содержать другие блоки через contentIds, а каждый потомок ссылается обратно через parentId. Блок с потомками по сути является страницей — открыть его значит перейти к его потомкам.

TypeScript
// A database block holds its rows as children.
// In saved JSON the hierarchy fields are named `content` and `parent`;
// on live Block objects (and the React BlockNode) the same links are
// exposed as `contentIds` and `parentId`.
{
  id: 'db-1',
  type: 'database',
  data: { schema: [/* columns */], views: [/* configs */] },
  content: ['row-1', 'row-2'], // its children
}

// A row is a block that points back to its parent
{
  id: 'row-1',
  type: 'database-row',
  parent: 'db-1',
  data: { properties: { status: 'Done', priority: 'High' } },
}

Та же идея — на всех уровнях

То, что выглядит как отдельные системы, на деле — просто блоки, расставленные в дереве:

Это……является блоком, потому что
АбзацВ его data хранится текст и инлайн-форматирование.
База данныхВ её data хранятся схема и конфигурации представлений — это не отдельная таблица.
Строка базы данныхЭто потомок блока базы данных; её значения лежат в data.properties.
СтраницаЛюбой блок с потомками. Открытие переходит к его contentIds.

Что не является блоком

Структурированные значения свойств — статус, приоритет, срок у строки — это не блоки. Это метаданные, которые хранятся в data блока-владельца. Правило: если у сущности есть идентичность, она хранит содержимое и её можно вкладывать — это блок; если это типизированное значение, принадлежащее блоку, оно живёт в data этого блока.

Почему это важно для вас

Поскольку всё — это блок, вы осваиваете один набор приёмов, и он работает везде:

Один API для всего

insert, move и delete работают с любым блоком — абзацем, строкой или целой базой данных — одними и теми же вызовами.

Один формат сохранения

editor.save() обходит одно и то же дерево для любого контента, поэтому сохранение и отрисовка не требуют особых случаев.

Одна модель вложенности

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

Расширяете Blok? Задайте один вопрос

Прежде чем проектировать новую возможность, спросите: «Это блок?» Если она представляет контент, данные или контейнер — почти всегда да: реализуйте её как блок, а не придумывайте параллельную модель данных.

  • Представление-календарь → конфигурация представления на блоке базы данных; строки остаются блоками-строками.
  • Тред комментариев → блок.
  • Оглавление → блок, который читает соседние блоки.
  • Встраивание → блок.

Готовы работать с деревом напрямую? Смотрите Blocks API для вставки и перемещения блоков и BlockData для точной формы сохранённого блока.