feat: v1 system element library — all ContentElements as shortcode templates + sidecars #27

Closed
dominik.polakovics wants to merge 4 commits from afk/14 into main

Closes #14

Ships the complete v1 element library: every system element as a Hugo shortcode template (layouts/shortcodes/X.html) plus an editor sidecar (editor/elements/X.yaml) in the sample site, fully editable through #3's schema-generated forms.

What's included

Elements — Structure: grid/column (fixed six-step responsive width set as classes), spacer. Content: text, text-media, image, gallery/gallery-item, hero (reworked: heading param + markdown body with inline elements), quote, video-embed, accordion/accordion-item (details/summary), page-teasers, html. Inline: button, icon.

Contractdocs/elements.md documents the class vocabulary (ce-* BEM), placement metadata (accepts/within/inline, declared here for #6 to enforce), body policies, and the width/spacer scales. All markup is semantic and theme-agnostic: classes only, no inline styles, no CSS, no third-party assets.

Machinery (one minimal addition) — sidecars may declare hidden: true; the schema is still loaded, served, and editable in place, but stays out of the default picker. html ships hidden. This was the only spec-required flag inexpressible in #3's schema.

Privacyvideo-embed renders a local consent facade; verified zero <iframe>s and zero third-party src/href in the built site until click. The self-contained inline loader then builds the privacy-enhanced embed URL (youtube-nocookie.com, player.vimeo.com?dnt=1) client-side.

Draftspage-teasers filters where .RegularPages "Draft" false; verified the draft post never appears even when built with --buildDrafts (as the preview supervisor does).

Tests — one canonical round-trip corpus fixture per element (nesting for grid/gallery/accordion, inline button+icon inside bodies); TestSiteElementLibrary locks the full element set with groups/icons/hidden served by the API; TestSiteContentCanonical keeps all sample-site content byte-for-byte canonical; TestSiteSidecarsValid asserts zero sidecar validation errors.

Sample site — one example page per element under content/elements/, self-contained placeholder SVGs, and goldmark unsafe = true (required for inline shortcode output inside markdown bodies — documented in docs/elements.md). The pre-library notice demo element is removed; the home page uses the new hero.

Verification

  • go vet ./..., go test ./... (all packages), and the web suite: green
  • Full hugo --buildDrafts build of the sample site: 0 iframes, 0 third-party refs, 0 inline styles under /elements/, 0 placeholder/raw-HTML-omitted leaks, draft absent from teasers, inline button/icon render mid-sentence in the hero body

🤖 Generated with Claude Code

https://claude.ai/code/session_01L3Ry5memduD4ENKfZj4ksc

Closes #14 Ships the complete v1 element library: every system element as a Hugo shortcode template (`layouts/shortcodes/X.html`) plus an editor sidecar (`editor/elements/X.yaml`) in the sample site, fully editable through #3's schema-generated forms. ## What's included **Elements** — Structure: `grid`/`column` (fixed six-step responsive width set as classes), `spacer`. Content: `text`, `text-media`, `image`, `gallery`/`gallery-item`, `hero` (reworked: `heading` param + markdown body with inline elements), `quote`, `video-embed`, `accordion`/`accordion-item` (`details`/`summary`), `page-teasers`, `html`. Inline: `button`, `icon`. **Contract** — `docs/elements.md` documents the class vocabulary (`ce-*` BEM), placement metadata (`accepts`/`within`/`inline`, declared here for #6 to enforce), body policies, and the width/spacer scales. All markup is semantic and theme-agnostic: classes only, no inline styles, no CSS, no third-party assets. **Machinery (one minimal addition)** — sidecars may declare `hidden: true`; the schema is still loaded, served, and editable in place, but stays out of the default picker. `html` ships hidden. This was the only spec-required flag inexpressible in #3's schema. **Privacy** — `video-embed` renders a local consent facade; verified zero `<iframe>`s and zero third-party `src`/`href` in the built site until click. The self-contained inline loader then builds the privacy-enhanced embed URL (`youtube-nocookie.com`, `player.vimeo.com?dnt=1`) client-side. **Drafts** — `page-teasers` filters `where .RegularPages "Draft" false`; verified the draft post never appears even when built with `--buildDrafts` (as the preview supervisor does). **Tests** — one canonical round-trip corpus fixture per element (nesting for grid/gallery/accordion, inline button+icon inside bodies); `TestSiteElementLibrary` locks the full element set with groups/icons/hidden served by the API; `TestSiteContentCanonical` keeps all sample-site content byte-for-byte canonical; `TestSiteSidecarsValid` asserts zero sidecar validation errors. **Sample site** — one example page per element under `content/elements/`, self-contained placeholder SVGs, and `goldmark unsafe = true` (required for inline shortcode output inside markdown bodies — documented in `docs/elements.md`). The pre-library `notice` demo element is removed; the home page uses the new hero. ## Verification - `go vet ./...`, `go test ./...` (all packages), and the web suite: green - Full `hugo --buildDrafts` build of the sample site: 0 iframes, 0 third-party refs, 0 inline styles under `/elements/`, 0 placeholder/raw-HTML-omitted leaks, draft absent from teasers, inline button/icon render mid-sentence in the hero body 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01L3Ry5memduD4ENKfZj4ksc
A sidecar may declare 'hidden: true' to keep its element out of the
default element picker while remaining loadable, served by the API, and
editable where it already appears on a page. Needed by the html element
of the v1 library (#14).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3Ry5memduD4ENKfZj4ksc
Ship all v1 elements as semantic, theme-agnostic shortcode templates
plus editor sidecars: grid/column (fixed responsive width set), spacer,
text, text-media, image, gallery/gallery-item, hero (reworked: heading
plus markdown body with inline elements), quote, video-embed
(click-to-load consent facade, zero third-party requests before click),
accordion/accordion-item (details/summary), page-teasers (drafts always
excluded), html (hidden from the picker), and inline button and icon.

Markup contract, class vocabulary, and placement metadata are documented
in docs/elements.md; sidecar placement declares the container/item/inline
rules for #6 to enforce. The pre-library notice demo element is removed
and the sample home page now uses the new hero. TestSiteElementLibrary
locks the full set with groups, icons, and the html hidden flag.

Closes #14 acceptance: templates emit classes only — no inline styles,
no CSS, no JS except video-embed's self-contained consent loader.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3Ry5memduD4ENKfZj4ksc
One canonical example page per library element under content/elements/,
self-contained placeholder SVGs, and goldmark unsafe=true so inline
button/icon shortcodes inside markdown bodies render (nested shortcode
output reaches goldmark as raw HTML).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3Ry5memduD4ENKfZj4ksc
test(content): canonical corpus fixtures for every library element
All checks were successful
ci / build-and-test (pull_request) Successful in 2m38s
464c52bdbb
One round-trip fixture per v1 element (nesting covered for grid,
gallery, and accordion; inline button/icon inside bodies), locking each
element's serialized form. TestSiteContentCanonical additionally asserts
every sample-site content file stays byte-for-byte canonical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3Ry5memduD4ENKfZj4ksc
All checks were successful
ci / build-and-test (pull_request) Successful in 2m38s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/deckle!27
No description provided.