К содержанию

Навигация

Шаблоны, вставки и варианты

Recipe собирает страницу из повторно используемых шаблонов и фрагментов и выбирает варианты по настройкам. Эта глава описывает словарь Recipe и правила вставки, выбора и ссылок.

Словарь Recipe

Recipe (simai.composition.recipe) содержит пять понятий.

Понятие Что это
Шаблон (template) общая форма страницы или секции с параметрами и именованными местами вставки
Фрагмент (fragment) повторно используемая часть без параметров и мест вставки
Место вставки (insertSlot) точка внутри шаблона, куда вызывающий передаёт содержимое
Выбор (select) выбор одной ветви по значению настройки
Вход (input) объявленное значение извне: параметр, настройка сайта или содержимое

Если повторяемая часть должна принимать параметры или вложенные элементы, это шаблон, как бы она ни называлась в библиотеке. Ссылка на фрагмент с параметрами — ошибка. Так у каждого вида источника ровно одна проверяемая форма.

Записи Recipe

Каждая запись дерева Recipe — ровно одно из трёх, всегда вместе с id:

  • node — обычный узел будущего Document;
  • ref — ссылка на шаблон или фрагмент;
  • select — выбор ветви.

Внутри слота узла допустима ещё одна запись — insertSlot, место вставки шаблона (см. Словарь Recipe). Корнем Recipe она быть не может.

Значения внутри узла тоже обёрнуты одной оболочкой: literal (готовое JSON, без подстановок внутри), input (объявленный вход Recipe) или parameter (параметр ближайшего вызова шаблона). Ни преобразования типов, ни вычисления выражений нет.

Пример: статья с двумя шапками

Шаблон статьи объявляет места вставки header и main. Recipe передаёт в header выбор между краткой и расширенной шапкой, а в main — текст статьи:

JSON
"slots": {
  "header": [{
    "id": "header-choice",
    "select": {
      "value": {"input": "headerMode"},
      "cases": {
        "compact": {"id": "chosen-header", "ref": {"kind": "fragment", "owner": "example/library",
                    "ref": "header.compact", "policy": "pinned", "revision": "r1"}},
        "expanded": {"id": "chosen-header", "ref": {"kind": "fragment", "owner": "example/library",
                    "ref": "header.expanded", "policy": "pinned", "revision": "r1"}}
      }
    }
  }],
  "main": [{
    "id": "body",
    "node": {
      "type": "content.paragraph",
      "data": {"content": {"input": "body"}},
      "bindings": [{"input": "body", "target": "content"}]
    }
  }]
}

При headerMode = expanded Document выглядит так: страница → секция с заголовком «Расширенная шапка» и строкой «Дополнительная строка шапки» → абзац с текстом статьи. При compact строки нет. Обратите внимание: в Document нет команды «выбери вариант» — выбор уже сделан.

Полный Recipe, источники и ожидаемые результаты обоих режимов — в проверяемом JSON; работающий пример — в главе Пример: статья с двумя шапками.

Правила вставки

  • Переданный слот заменяет содержимое по умолчанию из шаблона.
  • Отсутствующий слот использует содержимое по умолчанию.
  • Пустой массив [] намеренно очищает место.
  • Переданный, но нигде не использованный слот — ошибка: иначе потерялись бы данные автора.
  • Ограничения слота проверяются после раскрытия, а затем ещё раз по манифесту конечного типа.

Правила выбора

  • Значение выбора — строка из заранее перечисленного набора. Условий на JavaScript в Recipe нет.
  • Если вход не передан, берётся его значение по умолчанию; затем — явная ветвь missingCase.
  • Неизвестное значение, отказ доступа или ошибка источника — ошибка, а не тихий переход к ветви по умолчанию.
  • Синтаксис проверяется у всех ветвей, а источник читается только у выбранной: Framework загружает источник только активного варианта. Поэтому правка неиспользуемой шапки не заставляет пересобирать страницу.

Закреплённые и следующие ссылки

Ссылка на шаблон или фрагмент называет владельца, имя и политику:

  • pinned (рекомендуемый выбор) — точная ревизия в поле revision; несовпадение даёт revision_mismatch;
  • follow-published — следовать за опубликованной ревизией через указатель pointer. Это явный выбор, и он попадает в перечень зависимостей отдельной записью.

Поле policy обязательно: ссылка без него отклоняется.

Ссылка, которая прямо или косвенно ведёт сама на себя, даёт reference_cycle с полной цепочкой вызовов.

Устойчивые идентификаторы

Каждый узел Document получает идентификатор, вычисленный из пути сборки: n- и SHA-256 от идентификатора Recipe и цепочки шагов (узел, ссылка, выбор, слот, вставка). Следствия:

  • перестановка соседей сохраняет идентификаторы;
  • перенос узла в другое место меняет идентификатор;
  • ревизия источника в идентификатор не входит — обновление шаблона не ломает ссылки на узлы.

Recipe как содержимое страницы сайта

Recipe может быть содержимым обычной страницы сайта документации. В Docara Markdown-файл страницы хранит только заголовок и путь к JSON-описанию:

Markdown
---
title: Каталог товаров
composition_recipe: composition/catalog/descriptor.json
---

При сборке Docara получает HTML через модуль композиции из закреплённой поставки Framework, а затем добавляет обычную оболочку документации: меню, тему, поиск и навигацию. Исходники Framework для этого не нужны.

Смотрите также

Поиск по документации

Введите минимум 2 символа

    Настройки

    Тема
    Размер шрифта
    Ширина страницы