JSON динамического раздела
Раздел dynamic хранит один JSON-источник и при запуске viewer разворачивает его в корневую страницу и вложенное дерево виртуальных страниц. Источник, контент и Base64-ресурсы встраиваются в экспортированный HTML; внешний JSON endpoint не используется.
Полная структура
{
"schemaVersion": "1.0",
"settings": {
"navigation": {
"expandedByDefault": false,
"placement": "toc",
"showRootInToc": true
},
"search": { "enabled": true },
"toc": {
"enabled": true,
"minHeadingLevel": 2,
"maxHeadingLevel": 4
}
},
"styles": ".dynamic-badge { color: #2563eb; }",
"scripts": "console.log('Dynamic section page opened');",
"resources": [
{
"id": "logo",
"contentType": "image/png",
"encoding": "base64",
"content": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
"fileName": "logo.png"
}
],
"root": {
"contentType": "markdown",
"content": "# Каталог\n\n",
"toc": true,
"styles": ".dynamic-badge { font-weight: 700; }"
},
"pages": [
{
"id": "overview",
"title": "Обзор",
"slug": "overview",
"contentType": "markdown",
"content": "## Введение\n\nОткройте [подробности](ofd-page:details).",
"hidden": false,
"searchable": true,
"toc": true,
"scripts": "document.getElementById('main-article')?.setAttribute('data-page-ready', 'true');",
"children": [
{
"id": "details",
"title": "Подробности",
"slug": "details",
"contentType": "html",
"content": "<h2>Подробности</h2><img src=\"res://logo\" alt=\"Логотип\">"
}
]
}
]
}Обязательные поля
schemaVersionдолжно иметь значение"1.0".resourcesиpagesдолжны быть массивами, даже если они пусты.rootдолжен содержатьcontentTypeи строковое полеcontent.- Каждой странице нужны уникальный
id, непустойtitle,contentTypeи строковое полеcontent.
contentType принимает значение html или markdown. Формат каждой страницы выбирается независимо от корня и остальных страниц.
Настройки
settings.navigation.expandedByDefaultраскрывает навигацию по страницам при первом отображении.settings.navigation.placementпринимаетtoc,header-tocилиtoc-otp. Эти режимы размещают страницы и заголовки текущей страницы в оглавлении, шапке или панели «На этой странице».settings.navigation.showRootInTocопределяет, показывать ли ссылку на основной раздел в оглавлении. Значение по умолчанию —true.settings.search.enabledопределяет участие динамического раздела в поиске. Значение по умолчанию —true.settings.toc.enabledзадает стандартное поведение оглавления заголовков для корня и страниц.minHeadingLevelиmaxHeadingLevelпринимают значения от 1 до 6, минимум не может быть больше максимума.
Отсутствующие настройки нормализуются как свернутая навигация в toc с показом основного раздела, включенный поиск и выключенное оглавление заголовков с уровнями от 2 до 4.
Стили и скрипты
Необязательные строки styles и scripts верхнего уровня действуют для корня и всех виртуальных страниц. Объект root и каждая страница могут задать собственные необязательные styles и scripts. Сначала применяется код сохраненного section, затем общий код dynamic section и код конкретной страницы. Стили активны только при открытой странице, скрипты выполняются при каждом ее открытии.
Источники без этих полей остаются корректными источниками схемы 1.0 и работают как раньше.
Страницы и маршруты
slug становится сегментом маршрута страницы. Он может содержать строчные латинские буквы, цифры и одиночные дефисы. Если поле пропущено, значение создается из заголовка. Slug должен быть уникальным среди соседних страниц, а ID страницы — во всем источнике.
children содержит вложенные страницы. Источник может включать не более 2000 страниц с глубиной не более 10 уровней. hidden скрывает страницу из навигации, searchable со значением false исключает только эту страницу из поиска, а toc переопределяет общую настройку оглавления.
Для ссылки на другую виртуальную страницу используйте ofd-page:page-id. Указанный ID должен существовать.
Встроенные ресурсы
Каждому ресурсу нужны уникальный строчный id, непустой MIME contentType, encoding: "base64" и корректное непустое Base64-поле content. Необязательное поле fileName используется при открытии или скачивании файла. ID может содержать латинские буквы, цифры, точки, дефисы и подчеркивания.
Обращайтесь к ресурсу из HTML или Markdown через res://resource-id. Каждый указанный ID должен существовать. Исполняемые MIME-типы, HTML-документы, скрипты, inline event handlers, исполняемые URL и ресурсы, загружаемые через http:, https:, data: или blob:, отклоняются.
Проверка
Редактор показывает ошибки с путем к некорректному полю, например pages[2].content. Перед применением источника проверьте количество страниц, ресурсов и максимальную глубину. Сгенерированные страницы не хранятся как отдельные разделы: для изменения структуры или контента замените JSON.