Relationships
Informs 1
Related 10
Branches 4
Context
ADR-041 makes section the base that compositions place. The page-section runes (hero, cta, feature, pricing, reveal, tabs, accordion, steps) are expected to become compositions over it in time. Whatever section does with a leading paragraph or heading then becomes the header grammar of that whole family.
Today the family has two grammars, and they disagree:
| Content | Native page-section runes (pageSectionProperties, packages/runes/src/tags/common.ts) | section (packages/runes/src/tags/section.ts) |
|---|---|---|
| Paragraphs, no heading | the first paragraph is the blurb | the first paragraph is the eyebrow |
| Paragraph, then heading | eyebrow, then headline | eyebrow, then headline |
| Two headings | the first heading is the eyebrow | the second heading is body |
| Heading, then prose, then a paragraph | the first paragraph after the heading, anywhere, is the blurb | only a paragraph directly after the heading is the blurb |
Composition makes section's grammar read content that was never written as a header. A host runs its content model over the expanded template, so an author's paragraph arriving through a slot is matched by position like anything else:
- SPEC-169 D4's
stepsexample places each step with{% section %}{% slot /%}{% /section %}. A step's text is a paragraph with no heading before it, sosectionrenders it as an eyebrow: small, uppercase, in the primary colour. - A composed
testimonial(SPEC-161 D1) that places its quote and attribution slots in asectiongets the quote as the eyebrow and the attribution as the blurb. - The composed
character,realmandfactionescape only because their template places{% metablock %}between the heading and the description slot. Without it, the description's first paragraph would become a blurb. Nothing would report it.
A standalone section has the same problem, and WORK-652 makes it more common. With a media split, section becomes the general "region with media" primitive. An image beside two paragraphs then renders the first paragraph as an eyebrow.
Decision
The grammar is anchored to the headline. Eyebrow and blurb exist only relative to a headline. With no heading there is no header: all content is body. An eyebrow is a paragraph directly before the headline, and a blurb is a paragraph directly after it.
sectiontakesheader:auto(the default) reads eyebrow, headline and blurb as in decision 1;headlinelifts only the headline, so the paragraph after it stays body;nonereads no header at all: the region is all body.
The attribute applies wherever
sectionis used, standalone or placed by a composition. A composition sets it like any other attribute, for example{% section header="headline" %}.A slot that lands in a header role it is not named for is reported. At transform time, when content carrying a slot marker fills a header role and the slot's name is not that role's, the build warns, naming the composed rune, the slot, the role and both remedies. For example: "slot
descriptionofcharacteris read assection's blurb; name the fieldblurb, or setheader="headline"on the section." The warning changes nothing that renders.The page-section runes keep their native grammar until each one becomes a composition. A composed page-section rune parses its author's content with its own content model and places the result. It does not inherit
pageSectionProperties' rules throughsection.
Rationale
- The anchoring alone fixes every misreading found: the
stepsandtestimonialcases and the standalone region with media. None of them has a heading. - An attribute is visible and portable. It shows in the source, in
inspectand inreference, and means the same thing on a page and in a template. - The diagnostic is precise. The slot markers are already on the AST, so the check sees exactly which slot filled which role, with no static guessing about what a slot may contain.
- Deciding on
sectionnow is cheaper than later. Every composition placed on it after this inherits the grammar, and changing it then would move every one of them.
Consequences
section's output changes for content with no heading: a leading paragraph that rendered as an eyebrow is now body. The site's existingsectionexamples all have a heading, but the changeset names the change for third-party content.- SPEC-169 D4's
stepsexample renders its steps as body. headeris a new attribute onsection.referencedocuments it, and the editor offers it.
Open questions
- A heading used as an eyebrow.
hero,ctaandfeatureread two headings as an eyebrow heading and a headline.section's eyebrow is a paragraph only, so a composedherothat places a heading eyebrow would get the wrong headline. This is the one case where (b)'s binding by name is cleaner. It is decided with SPEC-160 D7, whenheroandctabecome compositions. The options are an eyebrow field that also takes a heading followed by another heading, or a composedherothat turns its heading eyebrow into a paragraph.
References
- ADR-041: section is the composition base.
- SPEC-160: D9 records this decision; D7 carries the open question.
- SPEC-145: D10a (slot markers); the host's positional grammar reads the template's arrangement.
- SPEC-169: D4's
stepsexample. - SPEC-170: D2, one meaning for a snippet wherever it is pasted.
- WORK-659: the implementation.