Skip to content

Synthesize template parts only from separable chrome - #678

Open
chubes4 wants to merge 1 commit into
mainfrom
fix/separable-chrome-template-parts
Open

Synthesize template parts only from separable chrome#678
chubes4 wants to merge 1 commit into
mainfrom
fix/separable-chrome-template-parts

Conversation

@chubes4

@chubes4 chubes4 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

When the Blocks Engine plan emits no template parts, SSI synthesizes header/footer parts from source HTML landmarks. That fallback previously:

  • accepted a nested <nav> as the global header purely via class-name signal, producing a nav-only header part while the page body kept its full embedded header (duplicate chrome)
  • fell back to first_landmark_html, which grabbed any <header>/<footer> regardless of nesting — including chrome embedded inside <main> that the page body always renders itself
  • scanned source files in array order, so an alphabetically-earlier archive page could define the global header instead of the entrypoint

Single-root documents (e.g. Figma-transformer output, where every landmark lives inside main.figma-root) therefore rendered chrome twice: once from the synthesized part and once from the page body — and the part could come from the wrong page variant entirely.

Changes

  • A landmark is only extractable as shared chrome when it is separable — not a descendant of <main>. Applies to the document fragment decomposition (header, nav, footer) and the first_landmark_html fallback.
  • Source files are scanned entrypoint-first so the imported front page is the authoritative source for synthesized parts; the transformer adapter now passes entry_path through to materializer artifacts.
  • Classic static sites with body-level landmarks keep today's behavior (regression-tested).

Measured impact

Three-fixture production matrix (Fisiostetic, FSE Pilot Build Theme, Twenty Twenty-Five Community .fig transforms), front-page visual mismatch vs the served static source at threshold 0:

Fixture Before After
FSE Pilot Build Theme 45.55% 16.54%
Twenty Twenty-Five Community 42.22% 28.73%
Fisiostetic 32.15% 32.15% (unrelated cause, tracked separately)

Editor gate unchanged and fully green in the same runs: 727/727 native blocks, 0 core/html, 0 invalid, 365/365 browser-validated blocks.

How to test

  1. php tests/smoke-embedded-chrome-template-parts.php — 17 assertions: embedded chrome produces no parts and stays in the page body; classic body-level chrome still produces parts; entrypoint page wins over alphabetically-earlier files; nested-chrome entrypoint falls through to the next separable page.
  2. php tests/smoke-template-part-shell-dedupe.php
  3. php tests/smoke-template-chrome-dedupe.php
  4. php tests/smoke-theme-materializer-dry-run.php
  5. php tests/smoke-semantic-parity-diagnostics.php
  6. php tests/smoke-wordpress-site-plan-materializer.php

All pass locally.

AI disclosure

Implemented with OpenCode using openai/gpt-5.6-sol; all listed tests were run locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant