5.2 KiB
Gotham — templ → codeless .bnp port notes
This theme was ported from the bundled Go/templ gotham plugin (source kept in
port-source/ for reference) to a codeless .bnp (no Go, no plugin.wasm),
matching the art-deco reference theme's structure. Every block, page template,
override and the email wrapper is now a host-rendered .ninjatpl.
What maps 1:1 (faithful, no behavior change)
| Source (templ) | Codeless equivalent | Notes |
|---|---|---|
RenderGotham (default) |
templates/gotham/default.ninjatpl |
bn.Head/bn.BodyEnd/bn.AdminBypassBanner replaced by host-injected {{ head_html }} / {{ body_end_html }} / {{ admin_banner_html }}. <html class="dark"> hardcoded exactly as source (Gotham is always dark). |
RenderGothamLanding |
templates/gotham/landing.ninjatpl |
hero/main/cta/footer slots preserved. |
RenderGothamFullWidth |
templates/gotham/full-width.ninjatpl |
|
RenderGothamCentered |
templates/gotham/centered.ninjatpl |
|
FeaturesBlock + featuresComponent |
blocks/features.ninjatpl |
Inline icon SVG switch (chart/users/clock/star/default) ported verbatim as {% if %} chains. columns grid logic preserved. |
FooterBlock + footerComponent |
blocks/footer.ninjatpl |
Column grid + link-URL logic preserved (see PageID note below). |
StatsBlock + statsComponent / statsEmptyComponent |
blocks/stats.ninjatpl |
Uses the items content array (the only path StatsBlock ever took). Empty-state placeholder preserved. |
GothamHeadingBlock override |
templates/overrides/gotham/heading.ninjatpl |
Per-level base classes + text-accent preserved. |
GothamTextBlock override |
templates/overrides/gotham/text.ninjatpl |
prose prose-invert prose-amber preserved. |
GothamEmailWrapper |
templates/email/gotham.ninjatpl |
Var names (site_name, site_url, colors.background/card/foreground/muted/mutedForeground/border/primary, preview_text, logo_url, unsubscribe_url) match the host email-context contract — identical to the art-deco reference wrapper. |
assets/style.css |
assets/style.css |
Byte-identical (gotham-accent, gotham-accent-bg, gotham-card, gotham-glow, …). Host serves it as a static and links it via head_html. |
DefaultMasterPages() |
master_pages.json |
gotham:default-master with navbar / slot / gotham:footer. |
presets.json, fonts.json |
unchanged | Carried over as manifest JSON refs. |
Behavior gaps / decisions the parent should review
-
heroblock was NOT registered in the source.port-source/hero.go/hero.templ/schemas/hero.schema.jsonexist, butregister.gonever callsbr.Register(HeroBlockMeta, ...), andHeroBlockhas the CMS-internal builtin signature(ctx, content, _ []string)— it was dead code. Because the task explicitly asked for a hero port and thelandingtemplate exposes aheroslot, I ported it faithfully toblocks/hero.ninjatpl+hero.schema.jsonand registered it asgotham:hero. If the parent wants to match the original registered surface exactly, delete those two files and thegotham:heroentry inblocks/blocks.yaml— nothing else references it. -
stat_itemblock dropped (intentionally).port-source/stat_item.go(StatItemBlockMeta,Hidden: true) andstatItemComponentwere also never registered inregister.go, andStatsBlockrenders its items inline (never via astat_itemchild block). The child-block container path (statsContainerComponent/gridCols(childCount)) was likewise unused. No codeless equivalent was created; the inline stats rendering is fully preserved. -
Footer internal-page links are a placeholder, same as source. The templ
getLinkURLemitted/pages/<page_id>for a link withpage_idset, with a source comment "In production, this would be resolved to the actual page slug." The codeless template reproduces/pages/{{ link.page_id }}verbatim — it does not resolvepage_id→ real slug (the codeless block declares no data providers, and the source didn't resolve it either). Behavior is identical to the original; flagging only because it was already a known limitation. -
No computing logic required code. All templ helper functions (
gridCols,featureGridCols,footerGridCols,gothamHeadingBaseClass,parseHeadingLevel, the emailgotham*Colorfallbacks) are pure presentational branching and were fully expressed with{% if %}/|default:in ninjatpl. Nothing in the source needed a wasm guest, so the artifact is genuinely codeless.
Not ported (obsolete)
port-source/ also contains embed.go, registration.go, register.go,
text_override.go, heading_override.go — Go glue for the bundled/.so era.
None have a codeless equivalent (their concerns are now declarations in
manifest.yaml / blocks.yaml / master_pages.json). Delete port-source/
once the port is verified.
Scope / version
versionstarts at 1.0.0 (graduation from bundled).scopeset to @ninja per the port task. NOTE: the sibling reference themes (art-deco,brutalist) use@themes, and the dev registry has both scopes. Changeplugin.modif@themesis preferred.