HERON

Контракт данных · часть 4

theme.yaml

Четвёртая часть контракта данных: theme.yaml, паспорт темы. Что тема умеет рисовать, чего ждёт от сайта и как связывает страницы между собой.

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

Простыми словами

Если контент — это текст книги, то тема — её вёрстка: шрифты, цвета, где стоят картинки. theme.yaml — паспорт темы. В нём перечислено, какие виды страниц тема умеет рисовать (главная, страница услуги, статья блога) и каких секций ждёт каждый вид.

Благодаря этому разделению дизайн можно сменить, не переписав ни одной страницы: новая тема читает те же файлы и рисует их по-своему.

Пример. Тема, которая знает два вида страниц:

name: my-theme
types:
  home:
    uses: [intro, "services:checklist", "faq:faq"]
  service:
    uses: [intro, "what:list", "prices:table", "faq:faq"]

Страница типа service с секциями what, prices и faq получает ровно те блоки, которые дизайнер для них сделал. О секции, которую тема не знает, сборка сообщит в отчёте, поэтому опечатка в якоре не пропадёт молча.

Когда нужна эта страница. Когда вы делаете или меняете тему. Если вы только пишете тексты, её можно пропустить.

Паспорт темы

theme.yaml служит документацией и основой отчёта heron check, а не жёстким валидатором.

name: main
version: "1.0"
title: Тема сайта

# что тема ждёт от site.yaml. HERON проверит наличие, не вникая в смысл
requires:
  - contact.phone
  - organization.name

# формы, которые тема рисует. Их описание должно быть в site.yaml
forms: [callback]

modules:
  - breadcrumbs
  - prose
  - facts
  - list
  - alert-list
  - steps
  - timeline
  - faq
  - cards
  - quote
  - table
  - gallery
  - author

types:
  home:
    uses: [intro, about, services, faq]
    jsonld: [WebSite]
  category:
    uses: [intro, outro]
    jsonld: [CollectionPage]
  service:
    uses: [intro, quick-facts, what, who, how, faq]
    jsonld: [Service]
  article:
    uses: [intro]
    jsonld: [Article]
  page:
    uses: [intro]

# связи между страницами. HERON найдёт, проверит и построит обратную ссылку,
# не зная, что означает само отношение
links:
  - field: related
    type: service
    back: mentioned_in
  - field: topic           # поле во фронтматтере страницы-источника
    type: topic            # на страницы какого типа ссылается (необязательно)
    on: service            # у страниц какого типа поле должно быть
    required: 1            # сколько ссылок минимум

# пропорции и ширины, в которые HERON впишет мастера
images:
  widths: [400, 800, 1200, 1600]
  ratios: ["1:1", "16:9", "4:3"]   # что шаблоны могут попросить; режется только попрошенное
  formats: [avif, webp]
  fallback_width: 800              # запасной PNG/JPEG для обычной картинки — одна ширина

Тип страницы — это шаблон

Тип страницы реализуется файлом templates/ТИП.html — обычным шаблоном Jinja2, где порядок блоков виден сверху вниз:

{% extends "base.html" %}
{% block content %}
  {{ mod.breadcrumbs() }}
  {{ mod.hero() }}
  {{ mod.facts('quick-facts') }}
  {{ mod.prose('what') }}
  {{ mod.prose('who') }}
  {{ mod.list('contra') }}
  {{ mod.steps('how') }}
  {{ mod.timeline('recovery') }}
  {{ mod.prose('price') }}
  {{ mod.faq('faq') }}
  {% for p in page.related.get('related', []) %}
    {{ p.h1 }} → {{ p.url }}   {# ссылка на связанную страницу #}
  {% endfor %}
  {{ mod.call() }}
  {{ mod.author() }}
{% endblock %}

mod.prose('what') берёт секцию what; если её нет — не выводит ничего, ни заголовка, ни пустой рамки. Обвязка условиями вокруг каждого модуля не нужна.

Как секции получают форму и что приходит в модуль — в разделе формы секций, а как это выглядит на сайте — в справочнике форм.

Источник

Эта страница повторяет раздел 6 файла docs/spec/20-data-contract.md из ветки prod. Репозиторий обновляется первым: открыть файл на GitHub.