Site-defined content components: components.exs with verified attribute contracts
- Dominant language
- CSS
- Stars
- 1
- Forks
- 0
- Avg merge
- 26m
- Merged PRs (30d)
- 62
Description
## Problem
The content-component set is closed. `Cherry.Content.Components` hardcodes the `emit` clauses (`::figure`, `::video`, the five alert containers) and the diagnostics enumerate them by name. A site author who wants `::gallery` or `:::spoiler` has two escape hatches — raw HTML in markdown (reintroduces the theme-coupled markup components exist to prevent) or restructuring into templates — and neither is the answer.
## Proposal: site-root `components.exs`
Runtime-compiled like every other `.exs` escape hatch (config, theme manifests, the HEEx `components.exs` — all proven inside the release binary). Two design points:
1. **Declared attribute contracts, not just render functions.** Each component declares its kind (leaf/container) and attrs (required/optional); the render is a pure `attrs -> HTML` function or template string. Because the contract is data, `cherry check` gives user components the same first-class diagnostics the built-ins get — unknown attr, missing required, unclosed fence, file and line — for free. Nobody else's shortcode system verifies.
2. **Site wins lookup, mirroring theme overlays**: site component → framework component, so a site can also override `::figure`.
## Constraints
- Render functions must be pure — the determinism gate catches violations, but document it.
- Escaping helpers provided; safe-by-default output with an explicit raw door.
- Docs pair the feature with the `assets/custom.css` rung: new components need styling.
- A malformed `components.exs` is a config-load error naming the file, never a broken page.
## Stretch
A directive could delegate to a HEEx function component (`::gallery` → `<.gallery {attrs} />`), unifying the content and template component models into one.
Supersedes the "Shortcodes/components in markdown (Zola-style)" line in LATER.md — 0.2.0 shipped the framework-level set; the remaining gap is user-defined components.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading Cherry.Content.Components and the existing config, theme-manifest, and HEEx components.exs loading paths described in the issue. Trace how built-in attributes and diagnostics are handled, then compare the proposal with LATER.md. Done means a site-root components.exs supports verified leaf/container contracts, site-over-framework lookup, safe rendering, and the documented assets/custom.css styling guidance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elixir
- Domain
- content
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100