fix: handle Anki conditional blocks in template gallery preview#2482
Merged
Conversation
The template gallery and editor preview both ran every starter through
a substituter that only knew about {{Field}} and {{cloze:Field}} — no
support for the {{#Field}}...{{/Field}} and {{^Field}}...{{/Field}}
section syntax Anki templates rely on, and no support for field names
with spaces.
Hits half the gallery the moment the iframe actually renders again
after the React Compiler revert: Image Occlusion (uses {{#Header}} and
{{#Back Extra}}), every Notion variant on the cloze base type (uses
{{#Extra}}), the Abhiyan Night Mode pair (uses {{#Tags}}), and the
Modern Cloze / Vocabulary / Medical / etc. starters in
DefaultTemplatesService (use {{#Example}}, {{#Mnemonic}}). Thumbnails
either rendered the literal {{#Field}} / {{/Field}} tokens or went
blank when an entire layout sat inside a section block.
Pre-existing since the note-types page shipped on 2026-05-15, masked
until now by the iframe-srcDoc freeze from #2465.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for notion2anki ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
6 tasks
aalemayhu
added a commit
that referenced
this pull request
May 20, 2026
…2483) ## Summary Template gallery thumbnails at \`/templates\` were rendering into an 800×450 internal iframe and CSS-scaling down to fit ~280px gallery cards — scale factor ~0.35. Text designed for full-screen Anki review ended up at ~5–6px effective, so most thumbnails looked empty even though their CSS and content were correct. This was a pre-existing weakness of the thumbnail design (since 2026-05-15) that the conditional-blocks fix from #2482 just exposed — before that, the literal \`{{#Field}}\` / \`{{/Field}}\` tokens filled space and gave the cards a sense of populated content; with proper section handling, the actual minimal designs are now visible. ## What changed \`web/src/pages/TemplatesPage/TemplatesPage.module.css\` — \`.previewFrame\`: | | Before | After | |---|---|---| | Internal width | 800px | 400px | | Internal height | 450px | 225px | | Scale | calc(100cqw / 800px) ≈ 0.35 | calc(100cqw / 400px) ≈ 0.7 | | Effective text @ 16px | ~5.6px | ~11.2px | Aspect ratio stays 16:9, no layout shift, no other CSS changes. The \`.modalFrame\` (click-to-zoom preview) is left at 800×600 — that surface exists for the full-fidelity preview. ## Test plan - [x] \`pnpm --filter 2anki-web vitest run src/pages/TemplatesPage\` — 44 tests pass - [x] \`pnpm --filter 2anki-web typecheck\` clean - [x] \`pnpm --filter 2anki-web lint\` clean - [ ] After deploy: open https://2anki.net/templates, confirm text is readable on Vocabulary Card, Medical Term, Quote, Math & Science, Modern Cloze, Clean Basic, Minimal, Code Card without zooming - [ ] Click into any card to open the modal preview, confirm full-fidelity 800×600 rendering still works ## Not building (deferred) - A static screenshot-per-template fallback (would fix Image Occlusion too, since its canvas needs JS that the sandbox blocks). Separate spec — multi-day work. - Resizing the modal preview. Reachable from any card; full fidelity is the right call there. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/2anki/codesmith/server/pr/2483"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-in-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-in-codesmith-light.svg"><img alt="View in Codesmith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-in-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith</code> with what you need.</sup> - [ ] Let Codesmith autofix CI failures and bot reviews <!-- /codesmith:footer --> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
aalemayhu
added a commit
that referenced
this pull request
May 20, 2026
…2484) ## Summary Two gallery fixes in the same surface, prompted by user feedback after #2482 + #2483 deployed. ### 1. Cards fill the iframe edge to edge \`notion.css\` ships with \`body { margin: 2em auto; max-width: 900px }\` — that meant every Notion-flavoured starter (Default Basic/Cloze/Type-the-answer, Only Notion variants) rendered with a band of the gallery card background showing through the top and bottom of the iframe. Visible as a \"offset\" between the preview wrap and the card content. Separately, \"Raw Note (no style)\" has \`cssFile: null\` so \`noteType.css\` is empty — the wrapper left both html and body transparent, so the thumbnail showed whatever was behind the iframe. Fix in \`renderNoteTypePreview.ts > buildPreviewDocument\`: - Wrapper sets a default \`background: #fff; color: #111\` on html and body. - Wrapper re-asserts \`margin: 0 / padding: 0 / max-width: none / width: 100% / height: 100%\` on html and body *after* the template CSS, with \`!important\` so notion.css's \`body { margin: 2em auto; max-width: 900px }\` no longer wins. - Templates that set their own \`.card\` background (Quote = #1c1917, Alex Deluxe = blue gradient, Abhiyan = night-mode dark) still win because that selector is more specific than the body reset. ### 2. Section reorder — Starter note types lead the page Visible sections were ordered: 1. Your note types 2. Official 2anki templates 3. Starter note types Reordered to: 1. Your note types 2. **Starter note types** (Clean Basic, Modern Cloze, Vocabulary, Medical, Code, Minimal, Quote, Math & Science — polished designs) 3. Official 2anki templates (Default / Only Notion / Raw / Abhiyan / Alex variants) User's own work still leads. The polished gallery comes next so the first impression is the strong designs, not the historical defaults. ## Test plan - [x] \`pnpm --filter 2anki-web vitest run src/pages/TemplatesPage\` — 44 tests pass - [x] \`pnpm --filter 2anki-web typecheck\` clean - [x] \`pnpm --filter 2anki-web lint\` clean - [ ] After deploy: hard-refresh \`/templates\`, confirm Only Notion thumbnails fill the iframe (no dark band top/bottom), confirm Raw Note (no style) has a white background, confirm Starter section appears above Official 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
The template gallery at `/templates` (and the editor preview behind it) both ran every starter through a tiny substituter that only knew about `{{Field}}` and `{{cloze:Field}}` — no support for the `{{#Field}}...{{/Field}}` and `{{^Field}}...{{/Field}}` section syntax Anki templates rely on, and no support for field names with spaces.
Production impact (visible right now after #2479 deployed)
Until the React Compiler revert landed, the iframes were frozen on first render so this bug was invisible. With the iframes updating again, half the gallery shows literal `{{#Tags}}` / `{{/Tags}}` tokens or goes blank:
User-reported (with screenshot): viewing Image Occlusion in the gallery shows `{{#Header}} Cell anatomy {{/Header}}` as plain text where the styled card should be.
Root cause
`web/src/pages/TemplatesPage/renderNoteTypePreview.ts`. Pre-existing since the note-types page shipped on 2026-05-15 (one commit ever on the file), masked until now by the iframe-srcDoc freeze from #2465 — so `/templates` looked broken in a different way for the last 18 hours and only the underlying "thumbnails are wrong" surfaced today.
What changed
`renderNoteTypePreview.ts`:
Six new tests in `renderNoteTypePreview.test.ts` cover: `#` block shows content when field present, `#` block hides when empty, `^` block inverse, field names with spaces, unknown-field cleanup, and the user-reported Image Occlusion case via `{{Back Extra}}`.
Test plan
Not a regression — clarifying the timeline
This bug is 5 days old, not 2. `renderNoteTypePreview.ts` has only one commit ever, from 2026-05-15. The user perceived it as a 2-day regression because (a) the iframe freeze from #2465 hid the bad output for the last 18 hours, and (b) the most-visited templates before that (Default Basic/Cloze) don't use conditional blocks and rendered fine.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need.