Relationships
Informs 1
Branches 3
Context
The rune authoring guide's "Content boundaries" section (site/content/extend/rune-authoring/patterns.md) says a rune's content model includes exactly what it reinterprets. Content that would render the same inside or outside the rune belongs on the page. It gives three tests:
- Does the rune give this content new meaning?
- Does it map to a structured-data field?
- Is the rune still portable without it?
For recipe, it puts "story, editorial, famous quotes" outside. A recipe is a semantic island in surrounding page prose.
Composition changes the premise of test 1. When a rune's layout was fixed rune CSS, prose inside it could only be appended, so including it bought coupling and nothing else. A composition's template is a layout language. Prose inside the rune can be placed between its parts, which prose outside it can never be. The common food-blog layout cannot be built today:
- the recipe's name, image and times on top;
- the story;
- a card with the ingredients and method.
The top belongs to the recipe, so the story has to sit between two parts of the rune.
Two constraints still hold, and one is new:
- The grammar would collide. Inside
{% recipe %}, a list is ingredients, an ordered list is steps and a blockquote is a tip. A story that contains a list of grandma's favourite markets would have them read as ingredients. Loose prose cannot simply be allowed. - Structured data (test 2). Unmapped visible content breaks neither schema.org nor search guidelines, as long as the published
Recipedescribes only the recipe. - Portability (test 3). A recipe embedded elsewhere carries whatever it contains. Today nothing embeds a recipe:
@refrakt-md/learningregisters no entities, and only plan entities providesourceFile+extract. The question becomes real once a composed rune can be embedded.
Decision
A rune may declare one narrative field that accepts the editorial runes
textblockandmediatext. For example:story: { match: "tag:textblock|tag:mediatext", optional: true, greedy: true }The resolver already supports this:
tag:NAME, pipe-separated alternatives, and a greedy field that collects a run of mixed blocks in source order (packages/runes/src/lib/resolver.ts).The narrative field is never mapped to structured data. The rune's schema row describes the rune, not the editorial around it.
Everything else the rune contains, it reinterprets. Loose prose inside the rune remains outside its content model.
It is opt-in per rune. The default stays a semantic island. Runes with an editorial layout, such as
recipe,howtoand possiblyevent, declare the field when they become compositions.Its place in the source is fixed; its place on the page is the template's. For
recipe, the field sits after the blurb and before the ingredients. The blocks must be consecutive, because asequencemodel matches in order.
Rationale
- It enables layouts that composition is meant to enable, without weakening the grammar: an editorial rune is a self-contained island inside the rune.
- No new rune and no parser change. The boundary is a rune authors already know.
- It is additive. A
textblockinside a recipe is acontent-unmatchederror today, so no page that builds now changes.
Consequences
- The "Content boundaries" section of the authoring guide is rewritten: the three tests stay, and a fourth case is added, an editorial rune as a declared narrative field, with the recipe layout as its example. The "What goes where" table gains a column or note for it.
- A recipe composition (SPEC-160 D5) can declare
story. Until then, nothing changes.
Open questions
- How a rune away from its own page shows its narrative. SPEC-178 proposes an answer. In full (
expand, a drawer preview), the rune renders through its canonical template, so the narrative appears where the template places it. As a summary (a popover, a hover card or a collection), it renders through a preview template that reads the registration and places no slots, so the narrative does not appear. This open question closes when SPEC-178 is accepted.
References
- SPEC-160: D5,
recipeoversection. - SPEC-177: D5 and D6, every slot placed and data shown.
- SPEC-178: entity previews.
- ADR-045: a theme may arrange a composed rune.