Skip to content

fix: handle Anki conditional blocks in template gallery preview#2482

Merged
aalemayhu merged 1 commit into
mainfrom
fix/template-conditional-blocks
May 20, 2026
Merged

fix: handle Anki conditional blocks in template gallery preview#2482
aalemayhu merged 1 commit into
mainfrom
fix/template-conditional-blocks

Conversation

@aalemayhu
Copy link
Copy Markdown
Contributor

@aalemayhu aalemayhu commented May 20, 2026

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:

  • Image Occlusion — uses `{{#Header}}...{{/Header}}` and `{{#Back Extra}}...{{/Back Extra}}`. Thumbnail goes blank.
  • Only Notion (Cloze) + every cloze-base official template — uses `{{#Extra}}...{{/Extra}}`.
  • Abhiyan Bhandari (Night Mode) + cloze variant — uses `{{#Tags}}{{Tags}}{{/Tags}}`. Renders literal token text.
  • Modern Cloze / Vocabulary Card / Medical Term etc. from `DefaultTemplatesService` — use `{{#Example}}` and `{{#Mnemonic}}` sections.

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`:

  1. New `resolveConditionals` runs before any field substitution. Fixed-point loop so nested `{{#X}}{{#Y}}...{{/Y}}{{/X}}` collapse correctly. `#` shows the inner content when the field is non-empty, `^` shows it when empty.
  2. `FIELD_RE` loosened to accept field names with spaces (`{{Back Extra}}`), with a negative lookahead so section delimiters don't get treated as field placeholders.
  3. `CLOZE_FIELD_RE` likewise loosened.
  4. Field-name lookups trim whitespace.

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

  • `pnpm --filter 2anki-web vitest run src/pages/TemplatesPage` — 44 tests pass (5 files)
  • `pnpm --filter 2anki-web typecheck` clean
  • After deploy: open https://2anki.net/templates, confirm Image Occlusion / Abhiyan / Modern Cloze thumbnails render the styled card (not literal `{{#X}}` text and not blank)
  • Open the preview modal on Image Occlusion, confirm both front and back render

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


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

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>
@netlify
Copy link
Copy Markdown

netlify Bot commented May 20, 2026

Deploy Preview for notion2anki ready!

Name Link
🔨 Latest commit 1e55029
🔍 Latest deploy log https://app.netlify.com/projects/notion2anki/deploys/6a0db1dc40a41a00089a3af7
😎 Deploy Preview https://deploy-preview-2482--notion2anki.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@aalemayhu aalemayhu merged commit 0a735fa into main May 20, 2026
9 checks passed
@aalemayhu aalemayhu deleted the fix/template-conditional-blocks branch May 20, 2026 13:08
@sonarqubecloud
Copy link
Copy Markdown

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>
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>
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