From 989f1fb51508d98bee45a80b6566052b9400afe3 Mon Sep 17 00:00:00 2001 From: Alex Dunmow Date: Sat, 4 Jul 2026 15:28:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20convert=20to=20codeless=20.bnp=20?= =?UTF-8?q?=E2=80=94=20templates=20+=20manifest,=20Go/templ=20deleted=20(W?= =?UTF-8?q?O-WZ-021)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- Makefile | 40 +- blocks/blocks.yaml | 42 ++ blocks/colophon.ninjatpl | 4 + {schemas => blocks}/colophon.schema.json | 0 blocks/cover_story.ninjatpl | 11 + {schemas => blocks}/cover_story.schema.json | 0 blocks/issue_archive.ninjatpl | 4 + {schemas => blocks}/issue_archive.schema.json | 0 blocks/masthead.ninjatpl | 7 + {schemas => blocks}/masthead.schema.json | 0 blocks/photo_essay.ninjatpl | 6 + {schemas => blocks}/photo_essay.schema.json | 0 blocks/pull_quote.ninjatpl | 7 + {schemas => blocks}/pull_quote.schema.json | 0 button_override.go | 33 -- button_override.templ | 13 - button_override_templ.go | 101 ---- colophon.go | 35 -- colophon.templ | 19 - colophon_templ.go | 65 --- cover_story.go | 41 -- cover_story.templ | 46 -- cover_story_templ.go | 141 ----- css.go | 191 ------- email_wrapper.go | 100 ---- email_wrapper.templ | 83 --- email_wrapper_templ.go | 344 ------------ embed.go | 49 -- go.mod | 20 - go.sum | 46 -- heading_override.go | 63 --- heading_override.templ | 21 - heading_override_templ.go | 291 ---------- helpers.go | 71 --- image_override.go | 23 - image_override.templ | 14 - image_override_templ.go | 111 ---- issue_archive.go | 43 -- issue_archive.templ | 37 -- issue_archive_templ.go | 138 ----- main.go | 17 - manifest.yaml | 218 ++++++++ master_pages.json | 25 + masthead.go | 37 -- masthead.templ | 18 - masthead_templ.go | 106 ---- photo_essay.go | 70 --- photo_essay.templ | 31 -- photo_essay_templ.go | 167 ------ plugin.mod | 5 +- pull_quote.go | 37 -- pull_quote.templ | 20 - pull_quote_templ.go | 89 --- register.go | 172 ------ registration.go | 39 -- template.templ | 246 --------- template_templ.go | 513 ------------------ templates/email/magazine-bold.ninjatpl | 53 ++ templates/magazine-bold/article.ninjatpl | 20 + templates/magazine-bold/default.ninjatpl | 17 + templates/magazine-bold/full-width.ninjatpl | 17 + templates/magazine-bold/landing.ninjatpl | 18 + .../overrides/magazine-bold/button.ninjatpl | 1 + .../overrides/magazine-bold/heading.ninjatpl | 1 + .../overrides/magazine-bold/image.ninjatpl | 1 + .../overrides/magazine-bold/text.ninjatpl | 1 + text_override.go | 19 - text_override.templ | 8 - text_override_templ.go | 67 --- 69 files changed, 472 insertions(+), 3821 deletions(-) create mode 100644 blocks/blocks.yaml create mode 100644 blocks/colophon.ninjatpl rename {schemas => blocks}/colophon.schema.json (100%) create mode 100644 blocks/cover_story.ninjatpl rename {schemas => blocks}/cover_story.schema.json (100%) create mode 100644 blocks/issue_archive.ninjatpl rename {schemas => blocks}/issue_archive.schema.json (100%) create mode 100644 blocks/masthead.ninjatpl rename {schemas => blocks}/masthead.schema.json (100%) create mode 100644 blocks/photo_essay.ninjatpl rename {schemas => blocks}/photo_essay.schema.json (100%) create mode 100644 blocks/pull_quote.ninjatpl rename {schemas => blocks}/pull_quote.schema.json (100%) delete mode 100644 button_override.go delete mode 100644 button_override.templ delete mode 100644 button_override_templ.go delete mode 100644 colophon.go delete mode 100644 colophon.templ delete mode 100644 colophon_templ.go delete mode 100644 cover_story.go delete mode 100644 cover_story.templ delete mode 100644 cover_story_templ.go delete mode 100644 css.go delete mode 100644 email_wrapper.go delete mode 100644 email_wrapper.templ delete mode 100644 email_wrapper_templ.go delete mode 100644 embed.go delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 heading_override.go delete mode 100644 heading_override.templ delete mode 100644 heading_override_templ.go delete mode 100644 helpers.go delete mode 100644 image_override.go delete mode 100644 image_override.templ delete mode 100644 image_override_templ.go delete mode 100644 issue_archive.go delete mode 100644 issue_archive.templ delete mode 100644 issue_archive_templ.go delete mode 100644 main.go create mode 100644 manifest.yaml create mode 100644 master_pages.json delete mode 100644 masthead.go delete mode 100644 masthead.templ delete mode 100644 masthead_templ.go delete mode 100644 photo_essay.go delete mode 100644 photo_essay.templ delete mode 100644 photo_essay_templ.go delete mode 100644 pull_quote.go delete mode 100644 pull_quote.templ delete mode 100644 pull_quote_templ.go delete mode 100644 register.go delete mode 100644 registration.go delete mode 100644 template.templ delete mode 100644 template_templ.go create mode 100644 templates/email/magazine-bold.ninjatpl create mode 100644 templates/magazine-bold/article.ninjatpl create mode 100644 templates/magazine-bold/default.ninjatpl create mode 100644 templates/magazine-bold/full-width.ninjatpl create mode 100644 templates/magazine-bold/landing.ninjatpl create mode 100644 templates/overrides/magazine-bold/button.ninjatpl create mode 100644 templates/overrides/magazine-bold/heading.ninjatpl create mode 100644 templates/overrides/magazine-bold/image.ninjatpl create mode 100644 templates/overrides/magazine-bold/text.ninjatpl delete mode 100644 text_override.go delete mode 100644 text_override.templ delete mode 100644 text_override_templ.go diff --git a/Makefile b/Makefile index 61245fb..dd33e81 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,27 @@ -# magazine-bold — build & publish helpers (wasm .bnp workflow) +# magazine-bold — build & publish helpers (CODELESS .bnp workflow, WO-WZ-021) # -# The theme compiles to a wasip1 reactor-mode wasm module packed into a .bnp -# artifact (`ninja plugin build`). The legacy .so path is retired (WO-WZ-015): -# the CMS is wasm-native and can no longer load .so plugins. Distribution is -# publish-to-registry -> InstallFromRegistry (hot-load, no restart). +# This theme is a CODELESS .bnp: pure declaration the host runs — blocks +# (blocks/blocks.yaml + .ninjatpl), page/system templates, template overrides, +# an email wrapper, master pages, presets, fonts and CSS in manifest.yaml. No +# Go, no templ, no plugin.wasm, no block/core dependency. `ninja plugin build` +# classifies the repo as codeless (no Go at the root) and packs the artifact +# with manifest.pb (codeless: true) and NO plugin.wasm. # # Usage: -# make build # compile wasm + pack magazine-bold-.bnp -# make verify # validate the built .bnp (layout/abi/name/size) -# make archive-check # prove a clean `git archive HEAD` compiles to wasm +# make build # pack magazine-bold-.bnp (codeless — no wasm) +# make verify # validate the built .bnp (loader-identical checks) +# make archive-check # prove a clean `git archive HEAD` still builds codeless # make publish # ninja plugin publish --bnp (to the active registry) -# make templ # regenerate templ Go files # make clean # remove build artefacts -.PHONY: build verify archive-check publish templ clean help +.PHONY: build verify archive-check publish clean help PLUGIN_NAME := magazine-bold NINJA := ninja BNP := $(PLUGIN_NAME)-$(shell grep '^version' plugin.mod | sed 's/.*"\(.*\)"/\1/').bnp -# Compile to wasm and pack the .bnp (GOOS=wasip1 GOARCH=wasm, DESCRIBE probe, -# tar.zst of plugin.wasm + plugin.mod + manifest.pb + schemas/ + assets/). +# Pack the codeless .bnp (manifest.pb synthesized from plugin.mod + manifest.yaml +# + blocks/ + templates/; no wasm compile, no DESCRIBE probe). build: $(NINJA) plugin build --dir . @@ -28,12 +29,12 @@ build: verify: $(NINJA) plugin verify $(BNP) -# Prove a clean `git archive HEAD` (what publish ships) compiles to wasm. +# Prove a clean `git archive HEAD` (what publish ships) still packs codeless. archive-check: @T=$$(mktemp -d /tmp/archive-check-$(PLUGIN_NAME).XXXXXX) && \ trap 'rm -rf "$$T"' EXIT && \ git archive HEAD | tar -x -C "$$T" && \ - cd "$$T" && GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o "$$T/check.wasm" . && \ + cd "$$T" && $(NINJA) plugin build --dir . && \ echo "archive-check OK" # Publish the prebuilt .bnp to the active registry. @@ -41,19 +42,14 @@ archive-check: publish: build $(NINJA) plugin publish --bnp $(BNP) -# Regenerate templ Go files locally. -templ: - templ generate - # Remove build artefacts. clean: - rm -f $(PLUGIN_NAME)-*.bnp $(PLUGIN_NAME).so plugin.wasm + rm -f $(PLUGIN_NAME)-*.bnp plugin.wasm help: @echo "Targets:" - @echo " build Compile wasm + pack the .bnp" + @echo " build Pack the codeless .bnp (no wasm)" @echo " verify Validate the built .bnp (loader-identical checks)" - @echo " archive-check Prove a clean git archive HEAD compiles to wasm" + @echo " archive-check Prove a clean git archive HEAD packs codeless" @echo " publish Publish the .bnp to the active registry" - @echo " templ Regenerate templ Go files" @echo " clean Remove build artefacts" diff --git a/blocks/blocks.yaml b/blocks/blocks.yaml new file mode 100644 index 0000000..30cc45b --- /dev/null +++ b/blocks/blocks.yaml @@ -0,0 +1,42 @@ +# Magazine Bold theme block definitions (codeless .bnp, WO-WZ-021). +# Keys are fully qualified (magazine-bold:) because the codeless loader +# registers definitions verbatim — there is no PluginBlockRegistry prefixing +# in the codeless path (unlike the wasm/templ path). The qualified keys match +# the hardcoded data-block attributes and the master_pages.json references. +blocks: + - key: magazine-bold:masthead + title: Issue Masthead + description: Wordmark, issue number and tagline strip — sits at the top of every page. + category: layout + schema: masthead.schema.json + template: masthead.ninjatpl + - key: magazine-bold:cover_story + title: Cover Story + description: 12-column asymmetric hero with kicker, oversized display headline, deck and cover image. + category: content + schema: cover_story.schema.json + template: cover_story.ninjatpl + - key: magazine-bold:photo_essay + title: Photo Essay + description: Numbered photo-essay with asymmetric frame spans (half / full / tall) and mono captions. + category: content + schema: photo_essay.schema.json + template: photo_essay.ninjatpl + - key: magazine-bold:pull_quote + title: Pull Quote + description: Color-block pull quote with rotating accent (pink / blue / lime). + category: content + schema: pull_quote.schema.json + template: pull_quote.ninjatpl + - key: magazine-bold:issue_archive + title: Issue Archive + description: Numbered list of back-issues driven by a bucket query. + category: navigation + schema: issue_archive.schema.json + template: issue_archive.ninjatpl + - key: magazine-bold:colophon + title: Colophon + description: Mono caption strip with credits and an optional social row. + category: layout + schema: colophon.schema.json + template: colophon.ninjatpl diff --git a/blocks/colophon.ninjatpl b/blocks/colophon.ninjatpl new file mode 100644 index 0000000..7cec6be --- /dev/null +++ b/blocks/colophon.ninjatpl @@ -0,0 +1,4 @@ +
+ {% if credits %}
{{ credits|safe }}
{% endif %} + {% if showSocial == "true" or showSocial == true %}{% endif %} +
diff --git a/schemas/colophon.schema.json b/blocks/colophon.schema.json similarity index 100% rename from schemas/colophon.schema.json rename to blocks/colophon.schema.json diff --git a/blocks/cover_story.ninjatpl b/blocks/cover_story.ninjatpl new file mode 100644 index 0000000..3c48542 --- /dev/null +++ b/blocks/cover_story.ninjatpl @@ -0,0 +1,11 @@ +
+
+
+
{% if kicker %}
{{ kicker }}
{% endif %}
+

{% if headline %}{{ headline|safe }}{% else %}Cover story{% endif %}

+
{% if deck %}
{{ deck|safe }}
{% endif %}
+
+ {% if image %}
{% endif %} + {% if link %}{% endif %} +
+
diff --git a/schemas/cover_story.schema.json b/blocks/cover_story.schema.json similarity index 100% rename from schemas/cover_story.schema.json rename to blocks/cover_story.schema.json diff --git a/blocks/issue_archive.ninjatpl b/blocks/issue_archive.ninjatpl new file mode 100644 index 0000000..14f1bb4 --- /dev/null +++ b/blocks/issue_archive.ninjatpl @@ -0,0 +1,4 @@ + diff --git a/schemas/issue_archive.schema.json b/blocks/issue_archive.schema.json similarity index 100% rename from schemas/issue_archive.schema.json rename to blocks/issue_archive.schema.json diff --git a/blocks/masthead.ninjatpl b/blocks/masthead.ninjatpl new file mode 100644 index 0000000..c50be68 --- /dev/null +++ b/blocks/masthead.ninjatpl @@ -0,0 +1,7 @@ +
+
+ {% if issueNo %}No. {{ issueNo }}{% endif %} + {% if tagline %}{{ tagline }}{% endif %} +
+ {% if date %}{{ date }}{% endif %} +
diff --git a/schemas/masthead.schema.json b/blocks/masthead.schema.json similarity index 100% rename from schemas/masthead.schema.json rename to blocks/masthead.schema.json diff --git a/blocks/photo_essay.ninjatpl b/blocks/photo_essay.ninjatpl new file mode 100644 index 0000000..f84e0b9 --- /dev/null +++ b/blocks/photo_essay.ninjatpl @@ -0,0 +1,6 @@ +
+
+ {% if title %}

{{ title }}

{% endif %} + {% if frames %}
{% for frame in frames %}{% if frame.image %}
{{ frame.caption }}
{{ forloop.Counter|stringformat:"%02d" }}{% if frame.caption %}{{ frame.caption }}{% endif %}
{% endif %}{% endfor %}
{% else %}
No frames yet.
{% endif %} +
+
diff --git a/schemas/photo_essay.schema.json b/blocks/photo_essay.schema.json similarity index 100% rename from schemas/photo_essay.schema.json rename to blocks/photo_essay.schema.json diff --git a/blocks/pull_quote.ninjatpl b/blocks/pull_quote.ninjatpl new file mode 100644 index 0000000..6be9546 --- /dev/null +++ b/blocks/pull_quote.ninjatpl @@ -0,0 +1,7 @@ + diff --git a/schemas/pull_quote.schema.json b/blocks/pull_quote.schema.json similarity index 100% rename from schemas/pull_quote.schema.json rename to blocks/pull_quote.schema.json diff --git a/button_override.go b/button_override.go deleted file mode 100644 index 0131e20..0000000 --- a/button_override.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// ButtonOverrideBlock renders the built-in button block with the Magazine Bold -// squared-ink treatment and accent hover. -// -// Built-in button content shape: {"label": "...", "url": "...", "variant": "primary|secondary|destructive"} -func ButtonOverrideBlock(ctx context.Context, content map[string]any) string { - label := getString(content, "label") - if label == "" { - // fall back to "text" — some older button blocks used that key. - label = getString(content, "text") - } - url := getString(content, "url") - if url == "" { - url = getString(content, "href") - } - variant := getString(content, "variant") - switch variant { - case "secondary", "destructive", "primary": - // ok - default: - variant = "primary" - } - - var buf bytes.Buffer - _ = mbButtonComponent(label, url, variant).Render(ctx, &buf) - return buf.String() -} diff --git a/button_override.templ b/button_override.templ deleted file mode 100644 index 15ed370..0000000 --- a/button_override.templ +++ /dev/null @@ -1,13 +0,0 @@ -package main - -// mbButtonComponent renders a squared-ink button with accent hover. -// All variants get the visible 2px ring on :focus-visible from .mb-button. -templ mbButtonComponent(label, url, variant string) { - if label != "" { - { label } - } -} diff --git a/button_override_templ.go b/button_override_templ.go deleted file mode 100644 index 99f49cb..0000000 --- a/button_override_templ.go +++ /dev/null @@ -1,101 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// mbButtonComponent renders a squared-ink button with accent hover. -// All variants get the visible 2px ring on :focus-visible from .mb-button. -func mbButtonComponent(label, url, variant string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - if label != "" { - var templ_7745c5c3_Var2 = []any{"mb-button", "mb-button-" + variant} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `button_override.templ`, Line: 11, Col: 10} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/colophon.go b/colophon.go deleted file mode 100644 index 5ac12fb..0000000 --- a/colophon.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ColophonBlockMeta is the mono caption strip with credits and optional social row. -var ColophonBlockMeta = blocks.BlockMeta{ - Key: "colophon", - Title: "Colophon", - Description: "Mono caption strip with credits and an optional social row.", - Source: "magazine-bold", - Category: blocks.CategoryLayout, -} - -// ColophonData is what the templ component consumes. -type ColophonData struct { - Credits string - ShowSocial bool -} - -// ColophonBlock renders the colophon strip. -// content keys: credits (richtext), showSocial (select "true"/"false"). -func ColophonBlock(ctx context.Context, content map[string]any) string { - data := ColophonData{ - Credits: getString(content, "credits"), - ShowSocial: getBool(content, "showSocial", false), - } - var buf bytes.Buffer - _ = colophonComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/colophon.templ b/colophon.templ deleted file mode 100644 index bc996e0..0000000 --- a/colophon.templ +++ /dev/null @@ -1,19 +0,0 @@ -package main - -// colophonComponent renders the mono colophon strip. -templ colophonComponent(data ColophonData) { -
- if data.Credits != "" { -
- @templ.Raw(data.Credits) -
- } - if data.ShowSocial { - - } -
-} diff --git a/colophon_templ.go b/colophon_templ.go deleted file mode 100644 index 55dbc3f..0000000 --- a/colophon_templ.go +++ /dev/null @@ -1,65 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// colophonComponent renders the mono colophon strip. -func colophonComponent(data ColophonData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Credits != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Credits).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.ShowSocial { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/cover_story.go b/cover_story.go deleted file mode 100644 index feaa377..0000000 --- a/cover_story.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// CoverStoryBlockMeta is the 12-column asymmetric hero anchoring the issue landing. -var CoverStoryBlockMeta = blocks.BlockMeta{ - Key: "cover_story", - Title: "Cover Story", - Description: "12-column asymmetric hero with kicker, oversized display headline, deck and cover image.", - Source: "magazine-bold", - Category: blocks.CategoryContent, -} - -// CoverStoryData is what the templ component consumes. -type CoverStoryData struct { - Kicker string - Headline string - Deck string - Image string - Link string -} - -// CoverStoryBlock renders the cover-story hero. -// content keys: kicker, headline (richtext), deck (richtext), image (media), link. -func CoverStoryBlock(ctx context.Context, content map[string]any) string { - data := CoverStoryData{ - Kicker: getString(content, "kicker"), - Headline: getString(content, "headline"), - Deck: getString(content, "deck"), - Image: blocks.ResolveMediaPath(getString(content, "image")), - Link: getString(content, "link"), - } - var buf bytes.Buffer - _ = coverStoryComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/cover_story.templ b/cover_story.templ deleted file mode 100644 index b786093..0000000 --- a/cover_story.templ +++ /dev/null @@ -1,46 +0,0 @@ -package main - -// coverStoryComponent renders the 12-column asymmetric cover hero. -// Note: the spec calls for an oversized display headline; this consumes -// `--font-heading` via .font-display and clamps via .text-folio. -templ coverStoryComponent(data CoverStoryData) { -
-
-
-
- if data.Kicker != "" { -
{ data.Kicker }
- } -
-
-

- if data.Headline != "" { - @templ.Raw(data.Headline) - } else { - Cover story - } -

-
-
- if data.Deck != "" { -
- @templ.Raw(data.Deck) -
- } -
-
- if data.Image != "" { -
- -
- } - if data.Link != "" { - - } -
-
-} diff --git a/cover_story_templ.go b/cover_story_templ.go deleted file mode 100644 index 9425b91..0000000 --- a/cover_story_templ.go +++ /dev/null @@ -1,141 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// coverStoryComponent renders the 12-column asymmetric cover hero. -// Note: the spec calls for an oversized display headline; this consumes -// `--font-heading` via .font-display and clamps via .text-folio. -func coverStoryComponent(data CoverStoryData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Kicker != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.Kicker) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `cover_story.templ`, Line: 12, Col: 81} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Headline != "" { - templ_7745c5c3_Err = templ.Raw(data.Headline).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Cover story") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Deck != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Deck).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Image != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
\"\"
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.Link != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/css.go b/css.go deleted file mode 100644 index 4ae2eb1..0000000 --- a/css.go +++ /dev/null @@ -1,191 +0,0 @@ -package main - -// magazineBoldUtilityCSS is appended into the host Tailwind input. It carries -// the editorial display-type utilities, font-slot classes, the hairline rule -// motif, the asymmetric grid utilities, and the per-accent pull-quote variants. -// -// All font-family references go through CSS variables per docs/FONTS.md. -// All color references go through `hsl(var(--token))` consumers of the 19 -// theme tokens — no hardcoded hex, rgb(), or named colors. Per-accent -// pull-quote variants intentionally key off the `--accent` token (which the -// active preset rotates between hot pink, electric blue and lime). -// -// The `data-mb-accent` attribute selectors let a pull-quote pin a specific -// accent independently of the preset — they map back into the theme token -// space using the HSL triples documented in the spec §4 accent rows. -const magazineBoldUtilityCSS = ` -/* =========================================================== - * Magazine Bold — theme utilities - * Appended to the Tailwind input via CSSManifest.InputCSSAppend. - * =========================================================== */ - -/* --- Font-slot classes (consume CMS-managed font variables) --- */ -.font-display { - font-family: var(--font-heading, "Playfair Display", "Cormorant Garamond", Georgia, "Times New Roman", serif); - font-feature-settings: "ss01", "ss02", "kern", "liga"; - font-optical-sizing: auto; -} -.font-serif-sub { - font-family: var(--font-heading, "Fraunces", "Playfair Display", Georgia, "Times New Roman", serif); -} -.font-sans { - font-family: var(--font-body, "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif); -} -.font-mono { - font-family: var(--font-mono, "JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); -} - -/* --- Display-size utilities ------------------------------- */ -/* text-folio: 220pt-equivalent oversized folio number / cover hit. - The clamp resolves to ~220px (~165pt) at 1440px, scaling down to 80px on mobile. */ -.text-folio { - font-family: var(--font-heading, "Playfair Display", Georgia, serif); - font-size: clamp(80px, 18vw, 240px); - line-height: 0.85; - letter-spacing: -0.04em; - font-weight: 200; - font-style: italic; -} -.text-deck { - font-family: var(--font-body, "Inter", system-ui, sans-serif); - font-size: clamp(28px, 3.2vw, 48px); - line-height: 1.15; - letter-spacing: -0.01em; - font-weight: 400; -} -.text-kicker { - font-family: var(--font-mono, "JetBrains Mono", monospace); - font-size: 12px; - text-transform: uppercase; - letter-spacing: 0.18em; - font-weight: 600; -} - -/* --- Hairline rule motif ---------------------------------- */ -.mb-hairline { border-color: hsl(var(--border)); border-width: 1px; } -.mb-hairline-top { border-top: 1px solid hsl(var(--border)); } -.mb-hairline-bottom { border-bottom: 1px solid hsl(var(--border)); } - -/* --- Asymmetric editorial grid ---------------------------- */ -.mb-grid-12 { - display: grid; - grid-template-columns: repeat(12, minmax(0, 1fr)); - gap: 1.5rem; -} -.mb-grid-asym-cover { - display: grid; - grid-template-columns: repeat(12, minmax(0, 1fr)); - gap: 2rem; - align-items: end; -} -.mb-col-folio { grid-column: 1 / span 2; } -.mb-col-headline { grid-column: 3 / span 7; } -.mb-col-deck { grid-column: 10 / span 3; } -.mb-col-image-wide { grid-column: 1 / -1; } - -@media (max-width: 1024px) { - .mb-grid-asym-cover { grid-template-columns: 1fr; gap: 1.25rem; } - .mb-col-folio, .mb-col-headline, .mb-col-deck { grid-column: 1 / -1; } -} - -/* --- Photo essay frame spans ------------------------------ */ -.mb-photo-grid { - display: grid; - grid-template-columns: repeat(12, minmax(0, 1fr)); - gap: 1.25rem; -} -.mb-frame-half { grid-column: span 6 / span 6; } -.mb-frame-full { grid-column: 1 / -1; } -.mb-frame-tall { grid-column: span 5 / span 5; grid-row: span 2; } - -@media (max-width: 768px) { - .mb-photo-grid { grid-template-columns: 1fr; } - .mb-frame-half, .mb-frame-full, .mb-frame-tall { grid-column: 1 / -1; grid-row: auto; } -} - -/* --- Color-block accent panels ---------------------------- */ -.colorblock-accent { - background-color: hsl(var(--accent)); - color: hsl(var(--accent-foreground)); -} - -/* --- Per-accent pull-quote variants ----------------------- * - * These let a pull_quote override the preset accent on a per-instance basis. - * They use literal HSL triples that match the spec §4 accent values so a - * "pink" pull-quote always reads pink even on the ink-blue preset. - */ -[data-mb-accent="pink"] { --mb-accent-h: 330; --mb-accent-s: 95%; --mb-accent-l: 58%; } -[data-mb-accent="blue"] { --mb-accent-h: 220; --mb-accent-s: 100%; --mb-accent-l: 56%; } -[data-mb-accent="lime"] { --mb-accent-h: 78; --mb-accent-s: 90%; --mb-accent-l: 50%; } -[data-mb-accent] .mb-quote-bar { - background-color: hsl(var(--mb-accent-h) var(--mb-accent-s) var(--mb-accent-l)); -} -[data-mb-accent] .mb-quote-text { color: hsl(var(--foreground)); } - -/* --- Drop-cap (heading override) -------------------------- */ -.mb-dropcap::first-letter { - font-family: var(--font-heading, "Playfair Display", Georgia, serif); - font-style: italic; - font-weight: 200; - float: left; - font-size: 5.5em; - line-height: 0.85; - padding-right: 0.08em; - margin-top: 0.04em; - color: hsl(var(--foreground)); -} - -/* --- Body text override (Inter + margin folios) ----------- */ -.mb-body { - font-family: var(--font-body, "Inter", system-ui, sans-serif); - font-size: clamp(16px, 1.05vw, 18px); - line-height: 1.55; - letter-spacing: 0.005em; - color: hsl(var(--foreground)); -} - -/* --- Squared ink button ----------------------------------- */ -.mb-button { - display: inline-flex; - align-items: center; - gap: 0.5rem; - background-color: hsl(var(--primary)); - color: hsl(var(--primary-foreground)); - font-family: var(--font-mono, "JetBrains Mono", monospace); - font-size: 12px; - letter-spacing: 0.14em; - text-transform: uppercase; - padding: 0.875rem 1.5rem; - border: 1px solid hsl(var(--primary)); - border-radius: 0; - transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease; -} -.mb-button:hover { - background-color: hsl(var(--accent)); - color: hsl(var(--accent-foreground)); - border-color: hsl(var(--accent)); -} -.mb-button:focus-visible { - outline: 2px solid hsl(var(--ring)); - outline-offset: 2px; -} - -/* --- Caption (mono, used by image override + photo essay) -- */ -.mb-caption { - font-family: var(--font-mono, "JetBrains Mono", monospace); - font-size: 12px; - line-height: 1.45; - letter-spacing: 0.01em; - color: hsl(var(--muted-foreground)); -} - -/* --- Full-bleed image with numbered folio ----------------- */ -.mb-fullbleed { width: 100vw; max-width: 100vw; margin-left: 50%; transform: translateX(-50%); } -.mb-image-folio { - font-family: var(--font-mono, "JetBrains Mono", monospace); - font-size: 11px; - letter-spacing: 0.16em; - color: hsl(var(--muted-foreground)); - text-transform: uppercase; -} -` diff --git a/email_wrapper.go b/email_wrapper.go deleted file mode 100644 index 82c11ed..0000000 --- a/email_wrapper.go +++ /dev/null @@ -1,100 +0,0 @@ -package main - -import ( - "bytes" - "context" - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// MagazineBoldEmailWrapper wraps body content in the Magazine Bold email template. -// The template is a 600px paper-toned table with a PP Editorial New wordmark, -// an ink hairline, body in Inter 16/24, and a mono colophon strip. -func MagazineBoldEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = magazineBoldEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// Hex defaults map onto the paper-pink light preset so wallets / clients that -// don't ship custom colours still resolve to the brand's paper tone. -// Spec §4 paper-pink light: background `38 30% 96%` → ~#F7F2EB -// foreground `0 0% 8%` → ~#141414 -// border `0 0% 88%` → ~#E0E0E0 -// muted `38 20% 92%`→ ~#EEE9E0 -// mutedFg `0 0% 40%` → ~#666666 -// accent `330 95% 58%` → ~#F0298A -func mbEmailBg(ctx templates.EmailContext) string { - if ctx.Colors.Background != "" { - return ctx.Colors.Background - } - return "#F7F2EB" -} - -func mbEmailFg(ctx templates.EmailContext) string { - if ctx.Colors.Foreground != "" { - return ctx.Colors.Foreground - } - return "#141414" -} - -func mbEmailMuted(ctx templates.EmailContext) string { - if ctx.Colors.Muted != "" { - return ctx.Colors.Muted - } - return "#EEE9E0" -} - -func mbEmailMutedFg(ctx templates.EmailContext) string { - if ctx.Colors.MutedForeground != "" { - return ctx.Colors.MutedForeground - } - return "#666666" -} - -func mbEmailBorder(ctx templates.EmailContext) string { - if ctx.Colors.Border != "" { - return ctx.Colors.Border - } - return "#E0E0E0" -} - -func mbEmailCard(ctx templates.EmailContext) string { - if ctx.Colors.Card != "" { - return ctx.Colors.Card - } - return "#FFFFFF" -} - -// mbEmailDisplayStack is the serif fallback the wordmark falls back to in -// clients that strip @font-face (Outlook 365 web). System serifs only. -const mbEmailDisplayStack = `'PP Editorial New', Georgia, 'Times New Roman', serif` - -// mbEmailBodyStack is the sans fallback used for body copy in clients that -// strip @font-face. -const mbEmailBodyStack = `'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif` - -// mbEmailMonoStack is the mono fallback used for the colophon strip. -const mbEmailMonoStack = `'JetBrains Mono', 'Courier New', Courier, monospace` - -// mbEmailStyleBody styles the outer body tag. -func mbEmailStyleBody(ctx templates.EmailContext) string { - return fmt.Sprintf("background-color: %s; margin: 0; padding: 0; font-family: %s;", mbEmailBg(ctx), mbEmailBodyStack) -} - -func mbEmailStyleHeader(ctx templates.EmailContext) string { - return fmt.Sprintf("padding: 32px 40px; background-color: %s; border-bottom: 1px solid %s;", mbEmailCard(ctx), mbEmailBorder(ctx)) -} - -func mbEmailStyleWordmark(ctx templates.EmailContext) string { - return fmt.Sprintf("margin: 0; font-family: %s; font-style: italic; font-weight: 200; font-size: 42px; line-height: 1; letter-spacing: -0.02em; color: %s;", mbEmailDisplayStack, mbEmailFg(ctx)) -} - -func mbEmailStyleBodyContent(ctx templates.EmailContext) string { - return fmt.Sprintf("padding: 40px 48px; background-color: %s; color: %s; font-family: %s; font-size: 16px; line-height: 24px;", mbEmailCard(ctx), mbEmailFg(ctx), mbEmailBodyStack) -} - -func mbEmailStyleColophon(ctx templates.EmailContext) string { - return fmt.Sprintf("padding: 24px 48px; background-color: %s; border-top: 1px solid %s; font-family: %s; font-size: 12px; line-height: 18px; color: %s; letter-spacing: 0.08em; text-transform: uppercase;", mbEmailMuted(ctx), mbEmailBorder(ctx), mbEmailMonoStack, mbEmailMutedFg(ctx)) -} diff --git a/email_wrapper.templ b/email_wrapper.templ deleted file mode 100644 index 13ee7a1..0000000 --- a/email_wrapper.templ +++ /dev/null @@ -1,83 +0,0 @@ -package main - -import ( - "fmt" - "git.dev.alexdunmow.com/block/core/templates" -) - -// magazineBoldEmailTemplate is the 600px paper-toned editorial email wrapper. -// It uses inlined hex defaults that map onto the paper-pink light preset so the -// layout reads correctly in clients that strip server CSS. -templ magazineBoldEmailTemplate(emailCtx templates.EmailContext, body string) { - - - - - - - - { emailCtx.SiteSettings.SiteName } - - - - if emailCtx.PreviewText != "" { -
- { emailCtx.PreviewText } -
- } - - - - -
- - - - - - - - - - - - - - - - - - -
- - -} diff --git a/email_wrapper_templ.go b/email_wrapper_templ.go deleted file mode 100644 index 8c5ed75..0000000 --- a/email_wrapper_templ.go +++ /dev/null @@ -1,344 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "fmt" - "git.dev.alexdunmow.com/block/core/templates" -) - -// magazineBoldEmailTemplate is the 600px paper-toned editorial email wrapper. -// It uses inlined hex defaults that map onto the paper-pink light preset so the -// layout reads correctly in clients that strip server CSS. -func magazineBoldEmailTemplate(emailCtx templates.EmailContext, body string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SiteName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 19, Col: 42} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.PreviewText != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.PreviewText) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 34, Col: 27} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.LogoURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else if emailCtx.SiteSettings.SiteName != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SiteName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 47, Col: 87} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
 
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(body).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SiteName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 64, Col: 46} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.SiteURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if emailCtx.UnsubscribeURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/embed.go b/embed.go deleted file mode 100644 index 101c4b3..0000000 --- a/embed.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "embed" - "io/fs" - "net/http" -) - -//go:embed assets/* -var assetsFS embed.FS - -//go:embed schemas/* -var schemasFS embed.FS - -//go:embed presets.json -var presetsData []byte - -//go:embed fonts.json -var fontsData []byte - -//go:embed plugin.mod -var pluginModBytes []byte - -// Assets returns the embedded assets filesystem. -func Assets() fs.FS { - sub, _ := fs.Sub(assetsFS, "assets") - return sub -} - -// Schemas returns the embedded schemas filesystem. -func Schemas() fs.FS { - sub, _ := fs.Sub(schemasFS, "schemas") - return sub -} - -// AssetsHandler returns an http.Handler that serves the embedded assets. -func AssetsHandler() http.Handler { - return http.FileServer(http.FS(Assets())) -} - -// ThemePresets returns the embedded theme presets JSON. -func ThemePresets() []byte { - return presetsData -} - -// BundledFonts returns the embedded fonts manifest JSON. -func BundledFonts() []byte { - return fontsData -} diff --git a/go.mod b/go.mod deleted file mode 100644 index 3030094..0000000 --- a/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module git.dev.alexdunmow.com/block/themes/magazine-bold - -go 1.26.4 - -require ( - git.dev.alexdunmow.com/block/core v0.15.2 - github.com/a-h/templ v0.3.1020 -) - -require ( - connectrpc.com/connect v1.20.0 // indirect - github.com/BurntSushi/toml v1.6.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.9.2 // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/text v0.36.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index ebd3d11..0000000 --- a/go.sum +++ /dev/null @@ -1,46 +0,0 @@ -connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= -connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= -git.dev.alexdunmow.com/block/core v0.15.2 h1:qTjJxa1pClxwehkdTxXiJDpHQLr5DoXBUCa40QRO0L8= -git.dev.alexdunmow.com/block/core v0.15.2/go.mod h1:A+mgA9oeWoPhXruv4Mjpywwl2A9B5I3cKzlJjalBdlE= -github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= -github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/a-h/templ v0.3.1020 h1:ypAT/L5ySWEnZ6Zft/5yfoWXYYkhFNvEFOeeqecg4tw= -github.com/a-h/templ v0.3.1020/go.mod h1:A2DlK61v+K+NRoGnhmYbNYVmtYHcFO5/AisMvBdDxTM= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= -github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU= -github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/heading_override.go b/heading_override.go deleted file mode 100644 index 378eabb..0000000 --- a/heading_override.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "bytes" - "context" - "strconv" -) - -// HeadingOverrideBlock renders headings with the Magazine Bold display-serif scale -// and an optional drop-cap on h1. -// -// Built-in heading content shape: {"text": "...", "level": 1-6, "textClass": "..."} -func HeadingOverrideBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - textClass := getString(content, "textClass") - level := parseHeadingLevel(content) - - var buf bytes.Buffer - _ = mbHeadingComponent(level, text, textClass).Render(ctx, &buf) - return buf.String() -} - -// parseHeadingLevel parses the level from content, defaulting to 2. -func parseHeadingLevel(content map[string]any) int { - if level, ok := content["level"].(float64); ok { - l := int(level) - if l >= 1 && l <= 6 { - return l - } - } - if level, ok := content["level"].(int); ok { - if level >= 1 && level <= 6 { - return level - } - } - if level, ok := content["level"].(string); ok { - if l, err := strconv.Atoi(level); err == nil && l >= 1 && l <= 6 { - return l - } - } - return 2 -} - -// mbHeadingBaseClass returns the Magazine Bold class for each heading level. -// h1 picks up the .text-folio clamp + drop-cap behaviour. -func mbHeadingBaseClass(level int) string { - switch level { - case 1: - return "font-display text-folio text-foreground mb-dropcap" - case 2: - return "font-display text-deck text-foreground" - case 3: - return "font-display text-3xl text-foreground" - case 4: - return "font-serif-sub text-2xl text-foreground" - case 5: - return "font-serif-sub text-xl text-foreground" - case 6: - return "font-mono text-kicker text-muted-foreground" - default: - return "font-display text-deck text-foreground" - } -} diff --git a/heading_override.templ b/heading_override.templ deleted file mode 100644 index 072c13d..0000000 --- a/heading_override.templ +++ /dev/null @@ -1,21 +0,0 @@ -package main - -// mbHeadingComponent renders a heading at the requested level with Magazine Bold scale. -templ mbHeadingComponent(level int, text, textClass string) { - switch level { - case 1: -

{ text }

- case 2: -

{ text }

- case 3: -

{ text }

- case 4: -

{ text }

- case 5: -
{ text }
- case 6: -
{ text }
- default: -

{ text }

- } -} diff --git a/heading_override_templ.go b/heading_override_templ.go deleted file mode 100644 index ddef8da..0000000 --- a/heading_override_templ.go +++ /dev/null @@ -1,291 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// mbHeadingComponent renders a heading at the requested level with Magazine Bold scale. -func mbHeadingComponent(level int, text, textClass string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch level { - case 1: - var templ_7745c5c3_Var2 = []any{mbHeadingBaseClass(1), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 7, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 2: - var templ_7745c5c3_Var5 = []any{mbHeadingBaseClass(2), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 9, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 3: - var templ_7745c5c3_Var8 = []any{mbHeadingBaseClass(3), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 11, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 4: - var templ_7745c5c3_Var11 = []any{mbHeadingBaseClass(4), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 13, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 5: - var templ_7745c5c3_Var14 = []any{mbHeadingBaseClass(5), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 15, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 6: - var templ_7745c5c3_Var17 = []any{mbHeadingBaseClass(6), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 17, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - var templ_7745c5c3_Var20 = []any{mbHeadingBaseClass(2), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 19, Col: 56} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/helpers.go b/helpers.go deleted file mode 100644 index b5288fe..0000000 --- a/helpers.go +++ /dev/null @@ -1,71 +0,0 @@ -package main - -// getString extracts a string value from content map. -func getString(content map[string]any, key string) string { - if v, ok := content[key].(string); ok { - return v - } - return "" -} - -// getInt extracts an int value from content map (handles float64 from JSON). -func getInt(content map[string]any, key string, defaultVal int) int { - if v, ok := content[key].(float64); ok { - return int(v) - } - if v, ok := content[key].(int); ok { - return v - } - return defaultVal -} - -// getBool extracts a bool from content (handles "true"/"false" strings). -func getBool(content map[string]any, key string, defaultVal bool) bool { - if v, ok := content[key].(bool); ok { - return v - } - if v, ok := content[key].(string); ok { - switch v { - case "true", "TRUE", "True", "1", "yes", "on": - return true - case "false", "FALSE", "False", "0", "no", "off", "": - return false - } - } - return defaultVal -} - -// getSlice extracts a slice of maps from content. -func getSlice(content map[string]any, key string) []map[string]any { - if v, ok := content[key].([]any); ok { - result := make([]map[string]any, 0, len(v)) - for _, item := range v { - if m, ok := item.(map[string]any); ok { - result = append(result, m) - } - } - return result - } - return nil -} - -// normalizeAccent maps the schema accent enum into a CSS class suffix. -// Unknown values fall back to "pink" (the default-preset accent slot). -func normalizeAccent(raw string) string { - switch raw { - case "pink", "blue", "lime": - return raw - default: - return "pink" - } -} - -// normalizeSpan maps the photo-essay frame span enum. -func normalizeSpan(raw string) string { - switch raw { - case "half", "full", "tall": - return raw - default: - return "half" - } -} diff --git a/image_override.go b/image_override.go deleted file mode 100644 index 13fb76a..0000000 --- a/image_override.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ImageOverrideBlock renders the built-in image block with the Magazine Bold -// treatment: optional full-bleed mode + a mono caption folio. -// -// Built-in image content shape: {"src": "...", "alt": "...", "caption": "...", "fullBleed": true/false} -func ImageOverrideBlock(ctx context.Context, content map[string]any) string { - src := blocks.ResolveMediaPath(getString(content, "src")) - alt := getString(content, "alt") - caption := getString(content, "caption") - fullBleed := getBool(content, "fullBleed", false) - - var buf bytes.Buffer - _ = mbImageComponent(src, alt, caption, fullBleed).Render(ctx, &buf) - return buf.String() -} diff --git a/image_override.templ b/image_override.templ deleted file mode 100644 index cad9de2..0000000 --- a/image_override.templ +++ /dev/null @@ -1,14 +0,0 @@ -package main - -// mbImageComponent renders an image with optional full-bleed mode and a numbered caption. -// Skips rendering if no src — guarantees zero broken . -templ mbImageComponent(src, alt, caption string, fullBleed bool) { - if src != "" { -
- { - if caption != "" { -
{ caption }
- } -
- } -} diff --git a/image_override_templ.go b/image_override_templ.go deleted file mode 100644 index 2a5f4d2..0000000 --- a/image_override_templ.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// mbImageComponent renders an image with optional full-bleed mode and a numbered caption. -// Skips rendering if no src — guarantees zero broken . -func mbImageComponent(src, alt, caption string, fullBleed bool) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - if src != "" { - var templ_7745c5c3_Var2 = []any{"my-8", templ.KV("mb-fullbleed", fullBleed)} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
\"") ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if caption != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(caption) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `image_override.templ`, Line: 10, Col: 64} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/issue_archive.go b/issue_archive.go deleted file mode 100644 index 38ec6fa..0000000 --- a/issue_archive.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// IssueArchiveBlockMeta is the numbered list of back-issues. -var IssueArchiveBlockMeta = blocks.BlockMeta{ - Key: "issue_archive", - Title: "Issue Archive", - Description: "Numbered list of back-issues driven by a bucket query.", - Source: "magazine-bold", - Category: blocks.CategoryNavigation, -} - -// IssueArchiveData is what the templ component consumes. -type IssueArchiveData struct { - BucketSlug string - Limit int -} - -// IssueArchiveBlock renders the issue archive list. -// content keys: bucketSlug (bucket-picker), limit (number). -// -// NOTE: bucket-row resolution is handled by the host at render-time via -// `bucket_data` injection — this block renders the scaffold and an empty -// state if the host hasn't supplied items yet. -func IssueArchiveBlock(ctx context.Context, content map[string]any) string { - data := IssueArchiveData{ - BucketSlug: getString(content, "bucketSlug"), - Limit: getInt(content, "limit", 12), - } - items := getSlice(content, "items") - if items == nil { - items = getSlice(content, "bucket_data") - } - var buf bytes.Buffer - _ = issueArchiveComponent(data, items).Render(ctx, &buf) - return buf.String() -} diff --git a/issue_archive.templ b/issue_archive.templ deleted file mode 100644 index 2e5b986..0000000 --- a/issue_archive.templ +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import "fmt" - -// issueArchiveComponent renders a numbered archive list. -// Unknown / empty bucket → renders an empty-state message, no broken markup. -templ issueArchiveComponent(data IssueArchiveData, items []map[string]any) { - -} diff --git a/issue_archive_templ.go b/issue_archive_templ.go deleted file mode 100644 index 9660673..0000000 --- a/issue_archive_templ.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "fmt" - -// issueArchiveComponent renders a numbered archive list. -// Unknown / empty bucket → renders an empty-state message, no broken markup. -func issueArchiveComponent(data IssueArchiveData, items []map[string]any) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/main.go b/main.go deleted file mode 100644 index 6d47d0b..0000000 --- a/main.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build wasip1 - -// Package main compiles the magazine-bold theme to a wasip1 reactor-mode wasm guest -// (WO-WZ-015). The .so build path is retired; `ninja plugin build` produces the -// .bnp artifact the registry serves. -// -// Reactor mode: the host runs `_initialize` once per pooled instance, which -// runs this init func (hence wasmguest.Serve) before any bn_invoke. Serve is -// non-blocking; all theme work then arrives over the ABI hook calls. main is -// never called. -package main - -import "git.dev.alexdunmow.com/block/core/plugin/wasmguest" - -func init() { wasmguest.Serve(Registration) } - -func main() {} // never called — reactor mode diff --git a/manifest.yaml b/manifest.yaml new file mode 100644 index 0000000..eefb0f5 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,218 @@ +# Magazine Bold theme — codeless .bnp manifest (WO-WZ-021 Phase B1). +# Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm). +theme_presets: presets.json +bundled_fonts: fonts.json +master_pages: master_pages.json + +system_templates: + - key: magazine-bold + title: Magazine Bold + description: "Editorial-print theme with oversized display type, asymmetric grids and rotating color-block accents for fashion, streetwear and culture publications." + +page_templates: + - system: magazine-bold + key: default + title: Default + description: "Standard editorial page with masthead, asymmetric main, footer colophon." + slots: [masthead, main, colophon] + - system: magazine-bold + key: landing + title: Issue Landing + description: "Cover-story hero plus issue navigation strip." + slots: [cover, secondary, main, colophon] + - system: magazine-bold + key: article + title: Article / Feature + description: "Long-form feature with deck, byline rail and pull-quote gutter." + slots: [masthead, deck, main, colophon] + - system: magazine-bold + key: full-width + title: Full Bleed + description: "Edge-to-edge photo-essay layout." + slots: [masthead, main, colophon] + +template_overrides: + - { template: magazine-bold, block: heading } + - { template: magazine-bold, block: text } + - { template: magazine-bold, block: image } + - { template: magazine-bold, block: button } + +email_wrappers: + - magazine-bold + +css: + input_css_append: | + /* =========================================================== + * Magazine Bold — theme utilities + * Appended to the Tailwind input via CSSManifest.InputCSSAppend. + * =========================================================== */ + + /* --- Font-slot classes (consume CMS-managed font variables) --- */ + .font-display { + font-family: var(--font-heading, "Playfair Display", "Cormorant Garamond", Georgia, "Times New Roman", serif); + font-feature-settings: "ss01", "ss02", "kern", "liga"; + font-optical-sizing: auto; + } + .font-serif-sub { + font-family: var(--font-heading, "Fraunces", "Playfair Display", Georgia, "Times New Roman", serif); + } + .font-sans { + font-family: var(--font-body, "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif); + } + .font-mono { + font-family: var(--font-mono, "JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); + } + + /* --- Display-size utilities ------------------------------- */ + /* text-folio: 220pt-equivalent oversized folio number / cover hit. + The clamp resolves to ~220px (~165pt) at 1440px, scaling down to 80px on mobile. */ + .text-folio { + font-family: var(--font-heading, "Playfair Display", Georgia, serif); + font-size: clamp(80px, 18vw, 240px); + line-height: 0.85; + letter-spacing: -0.04em; + font-weight: 200; + font-style: italic; + } + .text-deck { + font-family: var(--font-body, "Inter", system-ui, sans-serif); + font-size: clamp(28px, 3.2vw, 48px); + line-height: 1.15; + letter-spacing: -0.01em; + font-weight: 400; + } + .text-kicker { + font-family: var(--font-mono, "JetBrains Mono", monospace); + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.18em; + font-weight: 600; + } + + /* --- Hairline rule motif ---------------------------------- */ + .mb-hairline { border-color: hsl(var(--border)); border-width: 1px; } + .mb-hairline-top { border-top: 1px solid hsl(var(--border)); } + .mb-hairline-bottom { border-bottom: 1px solid hsl(var(--border)); } + + /* --- Asymmetric editorial grid ---------------------------- */ + .mb-grid-12 { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 1.5rem; + } + .mb-grid-asym-cover { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 2rem; + align-items: end; + } + .mb-col-folio { grid-column: 1 / span 2; } + .mb-col-headline { grid-column: 3 / span 7; } + .mb-col-deck { grid-column: 10 / span 3; } + .mb-col-image-wide { grid-column: 1 / -1; } + + @media (max-width: 1024px) { + .mb-grid-asym-cover { grid-template-columns: 1fr; gap: 1.25rem; } + .mb-col-folio, .mb-col-headline, .mb-col-deck { grid-column: 1 / -1; } + } + + /* --- Photo essay frame spans ------------------------------ */ + .mb-photo-grid { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + gap: 1.25rem; + } + .mb-frame-half { grid-column: span 6 / span 6; } + .mb-frame-full { grid-column: 1 / -1; } + .mb-frame-tall { grid-column: span 5 / span 5; grid-row: span 2; } + + @media (max-width: 768px) { + .mb-photo-grid { grid-template-columns: 1fr; } + .mb-frame-half, .mb-frame-full, .mb-frame-tall { grid-column: 1 / -1; grid-row: auto; } + } + + /* --- Color-block accent panels ---------------------------- */ + .colorblock-accent { + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + } + + /* --- Per-accent pull-quote variants ----------------------- * + * These let a pull_quote override the preset accent on a per-instance basis. + * They use literal HSL triples that match the spec §4 accent values so a + * "pink" pull-quote always reads pink even on the ink-blue preset. + */ + [data-mb-accent="pink"] { --mb-accent-h: 330; --mb-accent-s: 95%; --mb-accent-l: 58%; } + [data-mb-accent="blue"] { --mb-accent-h: 220; --mb-accent-s: 100%; --mb-accent-l: 56%; } + [data-mb-accent="lime"] { --mb-accent-h: 78; --mb-accent-s: 90%; --mb-accent-l: 50%; } + [data-mb-accent] .mb-quote-bar { + background-color: hsl(var(--mb-accent-h) var(--mb-accent-s) var(--mb-accent-l)); + } + [data-mb-accent] .mb-quote-text { color: hsl(var(--foreground)); } + + /* --- Drop-cap (heading override) -------------------------- */ + .mb-dropcap::first-letter { + font-family: var(--font-heading, "Playfair Display", Georgia, serif); + font-style: italic; + font-weight: 200; + float: left; + font-size: 5.5em; + line-height: 0.85; + padding-right: 0.08em; + margin-top: 0.04em; + color: hsl(var(--foreground)); + } + + /* --- Body text override (Inter + margin folios) ----------- */ + .mb-body { + font-family: var(--font-body, "Inter", system-ui, sans-serif); + font-size: clamp(16px, 1.05vw, 18px); + line-height: 1.55; + letter-spacing: 0.005em; + color: hsl(var(--foreground)); + } + + /* --- Squared ink button ----------------------------------- */ + .mb-button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + background-color: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); + font-family: var(--font-mono, "JetBrains Mono", monospace); + font-size: 12px; + letter-spacing: 0.14em; + text-transform: uppercase; + padding: 0.875rem 1.5rem; + border: 1px solid hsl(var(--primary)); + border-radius: 0; + transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease; + } + .mb-button:hover { + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + border-color: hsl(var(--accent)); + } + .mb-button:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + } + + /* --- Caption (mono, used by image override + photo essay) -- */ + .mb-caption { + font-family: var(--font-mono, "JetBrains Mono", monospace); + font-size: 12px; + line-height: 1.45; + letter-spacing: 0.01em; + color: hsl(var(--muted-foreground)); + } + + /* --- Full-bleed image with numbered folio ----------------- */ + .mb-fullbleed { width: 100vw; max-width: 100vw; margin-left: 50%; transform: translateX(-50%); } + .mb-image-folio { + font-family: var(--font-mono, "JetBrains Mono", monospace); + font-size: 11px; + letter-spacing: 0.16em; + color: hsl(var(--muted-foreground)); + text-transform: uppercase; + } diff --git a/master_pages.json b/master_pages.json new file mode 100644 index 0000000..a43d8cd --- /dev/null +++ b/master_pages.json @@ -0,0 +1,25 @@ +[ + { + "key": "magazine-bold:default-master", + "title": "Magazine Bold — Default", + "page_templates": ["default", "article"], + "blocks": [ + { "block_key": "navbar", "title": "Masthead Nav", "content": { "menuName": "main" }, "slot": "masthead", "sort_order": 0 }, + { "block_key": "magazine-bold:masthead", "title": "Issue Masthead", "content": { "issueNo": "01", "tagline": "Vol. 1 / Spring" }, "slot": "masthead", "sort_order": 1 }, + { "block_key": "slot", "title": "Main Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "magazine-bold:colophon", "title": "Colophon", "content": { "showSocial": "true" }, "slot": "colophon", "sort_order": 0 } + ] + }, + { + "key": "magazine-bold:landing-master", + "title": "Magazine Bold — Issue Landing", + "page_templates": ["landing", "full-width"], + "blocks": [ + { "block_key": "navbar", "title": "Masthead Nav", "content": { "menuName": "main" }, "slot": "masthead", "sort_order": 0 }, + { "block_key": "magazine-bold:cover_story", "title": "Cover Story", "content": { "issueNo": "01" }, "slot": "cover", "sort_order": 0 }, + { "block_key": "magazine-bold:issue_archive", "title": "Issue Archive", "content": { "bucketSlug": "issues" }, "slot": "secondary", "sort_order": 0 }, + { "block_key": "slot", "title": "Main Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "magazine-bold:colophon", "title": "Colophon", "content": { "showSocial": "true" }, "slot": "colophon", "sort_order": 0 } + ] + } +] diff --git a/masthead.go b/masthead.go deleted file mode 100644 index 9888342..0000000 --- a/masthead.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// MastheadBlockMeta is the issue-masthead (wordmark + folio bar) at the top of the page. -var MastheadBlockMeta = blocks.BlockMeta{ - Key: "masthead", - Title: "Issue Masthead", - Description: "Wordmark, issue number and tagline strip — sits at the top of every page.", - Source: "magazine-bold", - Category: blocks.CategoryLayout, -} - -// MastheadData is what the templ component consumes. -type MastheadData struct { - IssueNo string - Tagline string - Date string -} - -// MastheadBlock renders the issue masthead. -// content keys: issueNo, tagline, date — all optional, no panic on empty. -func MastheadBlock(ctx context.Context, content map[string]any) string { - data := MastheadData{ - IssueNo: getString(content, "issueNo"), - Tagline: getString(content, "tagline"), - Date: getString(content, "date"), - } - var buf bytes.Buffer - _ = mastheadComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/masthead.templ b/masthead.templ deleted file mode 100644 index bae533e..0000000 --- a/masthead.templ +++ /dev/null @@ -1,18 +0,0 @@ -package main - -// mastheadComponent renders the wordmark + folio strip. -templ mastheadComponent(data MastheadData) { -
-
- if data.IssueNo != "" { - No. { data.IssueNo } - } - if data.Tagline != "" { - { data.Tagline } - } -
- if data.Date != "" { - { data.Date } - } -
-} diff --git a/masthead_templ.go b/masthead_templ.go deleted file mode 100644 index 5c31fb0..0000000 --- a/masthead_templ.go +++ /dev/null @@ -1,106 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// mastheadComponent renders the wordmark + folio strip. -func mastheadComponent(data MastheadData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.IssueNo != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "No. ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.IssueNo) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `masthead.templ`, Line: 8, Col: 58} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.Tagline != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.Tagline) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `masthead.templ`, Line: 11, Col: 76} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Date != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.Date) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `masthead.templ`, Line: 15, Col: 72} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/photo_essay.go b/photo_essay.go deleted file mode 100644 index 4a652a8..0000000 --- a/photo_essay.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// PhotoEssayBlockMeta is the numbered photo-essay scaffolding. -var PhotoEssayBlockMeta = blocks.BlockMeta{ - Key: "photo_essay", - Title: "Photo Essay", - Description: "Numbered photo-essay with asymmetric frame spans (half / full / tall) and mono captions.", - Source: "magazine-bold", - Category: blocks.CategoryContent, -} - -// PhotoFrame is a single image in the photo essay. -type PhotoFrame struct { - Number int - Image string - Caption string - Span string -} - -// PhotoEssayData is what the templ component consumes. -type PhotoEssayData struct { - Title string - Frames []PhotoFrame -} - -// PhotoEssayBlock renders the photo essay scaffolding. -// content keys: title (text), frames (collection of {image, caption, span}). -func PhotoEssayBlock(ctx context.Context, content map[string]any) string { - rawFrames := getSlice(content, "frames") - frames := make([]PhotoFrame, 0, len(rawFrames)) - for i, item := range rawFrames { - img := blocks.ResolveMediaPath(getString(item, "image")) - // Skip frames that have no image (malformed-content safety). - if img == "" { - continue - } - frames = append(frames, PhotoFrame{ - Number: i + 1, - Image: img, - Caption: getString(item, "caption"), - Span: normalizeSpan(getString(item, "span")), - }) - } - data := PhotoEssayData{ - Title: getString(content, "title"), - Frames: frames, - } - var buf bytes.Buffer - _ = photoEssayComponent(data).Render(ctx, &buf) - return buf.String() -} - -// photoFrameSpanClass maps a span string to its CSS utility class. -func photoFrameSpanClass(span string) string { - switch span { - case "full": - return "mb-frame-full" - case "tall": - return "mb-frame-tall" - default: - return "mb-frame-half" - } -} diff --git a/photo_essay.templ b/photo_essay.templ deleted file mode 100644 index aa037ef..0000000 --- a/photo_essay.templ +++ /dev/null @@ -1,31 +0,0 @@ -package main - -import "fmt" - -// photoEssayComponent renders a numbered photo-essay grid. -templ photoEssayComponent(data PhotoEssayData) { -
-
- if data.Title != "" { -

{ data.Title }

- } - if len(data.Frames) == 0 { -
No frames yet.
- } else { -
- for _, frame := range data.Frames { -
- { -
- { fmt.Sprintf("%02d", frame.Number) } - if frame.Caption != "" { - { frame.Caption } - } -
-
- } -
- } -
-
-} diff --git a/photo_essay_templ.go b/photo_essay_templ.go deleted file mode 100644 index c2d45a6..0000000 --- a/photo_essay_templ.go +++ /dev/null @@ -1,167 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "fmt" - -// photoEssayComponent renders a numbered photo-essay grid. -func photoEssayComponent(data PhotoEssayData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Title != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.Title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `photo_essay.templ`, Line: 10, Col: 72} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if len(data.Frames) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
No frames yet.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, frame := range data.Frames { - var templ_7745c5c3_Var3 = []any{photoFrameSpanClass(frame.Span)} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
\"")
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", frame.Number)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `photo_essay.templ`, Line: 20, Col: 72} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if frame.Caption != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(frame.Caption) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `photo_essay.templ`, Line: 22, Col: 30} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/plugin.mod b/plugin.mod index 5f954ea..e3ffb2f 100644 --- a/plugin.mod +++ b/plugin.mod @@ -2,11 +2,8 @@ name = "magazine-bold" display_name = "Magazine Bold" scope = "@themes" -version = "0.1.2" +version = "0.2.0" description = "Editorial-print theme with oversized display type, asymmetric grids and rotating color-block accents for fashion, streetwear and culture publications." kind = "theme" categories = ["templates"] tags = ["fashion", "lifestyle", "streetwear", "magazine", "bold", "display", "music", "editorial", "art"] - -[compatibility] -block_core = ">=0.15.0 <0.16.0" diff --git a/pull_quote.go b/pull_quote.go deleted file mode 100644 index 796c03f..0000000 --- a/pull_quote.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// PullQuoteBlockMeta is the color-block pull quote. -var PullQuoteBlockMeta = blocks.BlockMeta{ - Key: "pull_quote", - Title: "Pull Quote", - Description: "Color-block pull quote with rotating accent (pink / blue / lime).", - Source: "magazine-bold", - Category: blocks.CategoryContent, -} - -// PullQuoteData is what the templ component consumes. -type PullQuoteData struct { - Quote string - Attribution string - Accent string -} - -// PullQuoteBlock renders the color-block pull quote. -// content keys: quote (richtext), attribution (text), accent (select). -func PullQuoteBlock(ctx context.Context, content map[string]any) string { - data := PullQuoteData{ - Quote: getString(content, "quote"), - Attribution: getString(content, "attribution"), - Accent: normalizeAccent(getString(content, "accent")), - } - var buf bytes.Buffer - _ = pullQuoteComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/pull_quote.templ b/pull_quote.templ deleted file mode 100644 index f8b2fee..0000000 --- a/pull_quote.templ +++ /dev/null @@ -1,20 +0,0 @@ -package main - -// pullQuoteComponent renders a pull quote anchored by an accent color bar. -// The accent value drives the data-mb-accent attribute, which the appended -// CSS uses to colour the .mb-quote-bar regardless of the active preset. -templ pullQuoteComponent(data PullQuoteData) { - -} diff --git a/pull_quote_templ.go b/pull_quote_templ.go deleted file mode 100644 index a0d3f96..0000000 --- a/pull_quote_templ.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// pullQuoteComponent renders a pull quote anchored by an accent color bar. -// The accent value drives the data-mb-accent attribute, which the appended -// CSS uses to colour the .mb-quote-bar regardless of the active preset. -func pullQuoteComponent(data PullQuoteData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/register.go b/register.go deleted file mode 100644 index 58b4e08..0000000 --- a/register.go +++ /dev/null @@ -1,172 +0,0 @@ -package main - -import ( - "context" - - "github.com/a-h/templ" - - "git.dev.alexdunmow.com/block/core/blocks" - "git.dev.alexdunmow.com/block/core/plugin" - "git.dev.alexdunmow.com/block/core/templates" -) - -// wrap adapts a templ-returning render function to templates.TemplateFunc. -func wrap(f func(ctx context.Context, doc map[string]any) templ.Component) templates.TemplateFunc { - return func(ctx context.Context, doc map[string]any) templates.HTMLComponent { - return f(ctx, doc) - } -} - -// Register is the plugin entry point that registers the Magazine Bold system -// template, page templates, blocks, overrides and email wrapper. -func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - tr.RegisterSystemTemplate(templates.SystemTemplateMeta{ - Key: "magazine-bold", - Title: "Magazine Bold", - Description: "Editorial-print theme with oversized display type, asymmetric grids and rotating color-block accents for fashion, streetwear and culture publications.", - }) - - // Page templates — slots per spec §6 / UAT §3. - if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{ - Key: "default", - Title: "Default", - Description: "Standard editorial page with masthead, asymmetric main, footer colophon.", - Slots: []string{"masthead", "main", "colophon"}, - }, wrap(RenderMagazineBold)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{ - Key: "landing", - Title: "Issue Landing", - Description: "Cover-story hero plus issue navigation strip.", - Slots: []string{"cover", "secondary", "main", "colophon"}, - }, wrap(RenderMagazineBoldLanding)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{ - Key: "article", - Title: "Article / Feature", - Description: "Long-form feature with deck, byline rail and pull-quote gutter.", - Slots: []string{"masthead", "deck", "main", "colophon"}, - }, wrap(RenderMagazineBoldArticle)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{ - Key: "full-width", - Title: "Full Bleed", - Description: "Edge-to-edge photo-essay layout.", - Slots: []string{"masthead", "main", "colophon"}, - }, wrap(RenderMagazineBoldFullWidth)); err != nil { - return err - } - - // Schemas BEFORE blocks (per UAT §3). - if err := br.LoadSchemasFromFS(Schemas()); err != nil { - return err - } - - // Theme blocks. - br.Register(MastheadBlockMeta, MastheadBlock) - br.Register(CoverStoryBlockMeta, CoverStoryBlock) - br.Register(PhotoEssayBlockMeta, PhotoEssayBlock) - br.Register(PullQuoteBlockMeta, PullQuoteBlock) - br.Register(IssueArchiveBlockMeta, IssueArchiveBlock) - br.Register(ColophonBlockMeta, ColophonBlock) - - // Built-in overrides — only active when this theme is selected. - br.RegisterTemplateOverride("magazine-bold", "heading", HeadingOverrideBlock) - br.RegisterTemplateOverride("magazine-bold", "text", TextOverrideBlock) - br.RegisterTemplateOverride("magazine-bold", "image", ImageOverrideBlock) - br.RegisterTemplateOverride("magazine-bold", "button", ButtonOverrideBlock) - - // Branded email wrapper. - tr.RegisterEmailWrapper("magazine-bold", MagazineBoldEmailWrapper) - - return nil -} - -// DefaultMasterPages returns the default master pages Magazine Bold seeds. -func DefaultMasterPages() []plugin.MasterPageDefinition { - return []plugin.MasterPageDefinition{ - { - Key: "magazine-bold:default-master", - Title: "Magazine Bold — Default", - PageTemplates: []string{"default", "article"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Masthead Nav", - Content: map[string]any{"menuName": "main"}, - Slot: "masthead", - SortOrder: 0, - }, - { - BlockKey: "magazine-bold:masthead", - Title: "Issue Masthead", - Content: map[string]any{"issueNo": "01", "tagline": "Vol. 1 / Spring"}, - Slot: "masthead", - SortOrder: 1, - }, - { - BlockKey: "slot", - Title: "Main Slot", - Content: map[string]any{"slotName": "main"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "magazine-bold:colophon", - Title: "Colophon", - Content: map[string]any{"showSocial": "true"}, - Slot: "colophon", - SortOrder: 0, - }, - }, - }, - { - Key: "magazine-bold:landing-master", - Title: "Magazine Bold — Issue Landing", - PageTemplates: []string{"landing", "full-width"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Masthead Nav", - Content: map[string]any{"menuName": "main"}, - Slot: "masthead", - SortOrder: 0, - }, - { - BlockKey: "magazine-bold:cover_story", - Title: "Cover Story", - Content: map[string]any{"issueNo": "01"}, - Slot: "cover", - SortOrder: 0, - }, - { - BlockKey: "magazine-bold:issue_archive", - Title: "Issue Archive", - Content: map[string]any{"bucketSlug": "issues"}, - Slot: "secondary", - SortOrder: 0, - }, - { - BlockKey: "slot", - Title: "Main Slot", - Content: map[string]any{"slotName": "main"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "magazine-bold:colophon", - Title: "Colophon", - Content: map[string]any{"showSocial": "true"}, - Slot: "colophon", - SortOrder: 0, - }, - }, - }, - } -} diff --git a/registration.go b/registration.go deleted file mode 100644 index 9115ed7..0000000 --- a/registration.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "io/fs" - "net/http" - - "git.dev.alexdunmow.com/block/core/blocks" - "git.dev.alexdunmow.com/block/core/plugin" - "git.dev.alexdunmow.com/block/core/templates" -) - -// Registration is the compile-time plugin registration for the Magazine Bold template. -var Registration = plugin.PluginRegistration{ - Name: "magazine-bold", - Version: plugin.ParseModVersion(pluginModBytes), - Register: func(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - return Register(tr, br) - }, - Assets: func() http.Handler { return AssetsHandler() }, - Schemas: func() fs.FS { return Schemas() }, - ThemePresets: func() []byte { return ThemePresets() }, - BundledFonts: func() []byte { return BundledFonts() }, - MasterPages: func() []plugin.MasterPageDefinition { return DefaultMasterPages() }, - CSSManifest: func() *plugin.CSSManifest { return ThemeCSSManifest() }, -} - -// ThemeCSSManifest returns the CSS manifest for Magazine Bold. The -// InputCSSAppend payload is appended into the host Tailwind input so the -// theme's display-type utilities (`.text-folio`, `.text-deck`, -// `.font-display`, etc.) and hairline rules ship with the compiled CSS. -// -// NOTE: per docs/FONTS.md, this pass does NOT inject @font-face declarations. -// The CMS emits @font-face automatically for fonts assigned via the picker. -// We only inject custom utility CSS here. -func ThemeCSSManifest() *plugin.CSSManifest { - return &plugin.CSSManifest{ - InputCSSAppend: magazineBoldUtilityCSS, - } -} diff --git a/template.templ b/template.templ deleted file mode 100644 index 4ff0217..0000000 --- a/template.templ +++ /dev/null @@ -1,246 +0,0 @@ -package main - -import ( - "context" - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// PageData carries the data the Magazine Bold page templates render. -type PageData struct { - Title string - Slots map[string]string - ThemeMode string - ThemeCSS string - SiteSettings bn.SiteSettingsData - PageMeta bn.PageMeta - StructuredData string - CSSHash string - PageviewNonce string - EngagementConfig bn.EngagementConfig -} - -func parseMagazineBoldPageData(doc map[string]any) PageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok { - title = t - } - - slots := make(map[string]string) - if s, ok := doc["slots"].(map[string]string); ok { - slots = s - } - - themeCSS := "" - if tc, ok := doc["theme_css"].(string); ok { - themeCSS = tc - } - - structuredData := "" - if sd, ok := doc["structured_data"].(string); ok { - structuredData = sd - } - - cssHash := "" - if ch, ok := doc["css_hash"].(string); ok { - cssHash = ch - } - - pageviewNonce := "" - if pn, ok := doc["pageview_nonce"].(string); ok { - pageviewNonce = pn - } - - themeMode := "light" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - siteSettings := bn.ParseSiteSettings(doc) - pageMeta := bn.ParsePageMeta(doc) - engagementConfig := bn.ParseEngagementConfig(doc) - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: siteSettings, - PageMeta: pageMeta, - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: engagementConfig, - } -} - -// mbHead reuses the core head component with the magazine-bold plugin style sheet. -templ mbHead(data PageData) { - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/magazine-bold/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) -} - -// MagazineBold — default page template. -// Slots: masthead, main, colophon. -templ MagazineBold(data PageData) { - - - @mbHead(data) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["masthead"]) -
-
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
No content blocks assigned to this page.
- } -
-
-
-
- @templ.Raw(data.Slots["colophon"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// MagazineBoldLanding — issue landing page template. -// Slots: cover, secondary, main, colophon. -templ MagazineBoldLanding(data PageData) { - - - @mbHead(data) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["cover"]) -
-
-
- @templ.Raw(data.Slots["secondary"]) -
-
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
No content blocks assigned to this page.
- } -
-
-
-
- @templ.Raw(data.Slots["colophon"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// MagazineBoldArticle — long-form feature template with deck and pull-quote gutter. -// Slots: masthead, deck, main, colophon. -templ MagazineBoldArticle(data PageData) { - - - @mbHead(data) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["masthead"]) -
-
-
-
- @templ.Raw(data.Slots["deck"]) -
-
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { -
- @templ.Raw(main) -
- } else { -
No content blocks assigned to this page.
- } -
-
-
-
- @templ.Raw(data.Slots["colophon"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// MagazineBoldFullWidth — edge-to-edge photo-essay template. -// Slots: masthead, main, colophon. -templ MagazineBoldFullWidth(data PageData) { - - - @mbHead(data) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["masthead"]) -
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
No content blocks assigned to this page.
- } -
-
-
- @templ.Raw(data.Slots["colophon"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// RenderMagazineBold renders the default page. -func RenderMagazineBold(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBold(parseMagazineBoldPageData(doc)) -} - -// RenderMagazineBoldLanding renders the issue-landing page. -func RenderMagazineBoldLanding(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBoldLanding(parseMagazineBoldPageData(doc)) -} - -// RenderMagazineBoldArticle renders the long-form article page. -func RenderMagazineBoldArticle(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBoldArticle(parseMagazineBoldPageData(doc)) -} - -// RenderMagazineBoldFullWidth renders the edge-to-edge photo-essay page. -func RenderMagazineBoldFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBoldFullWidth(parseMagazineBoldPageData(doc)) -} diff --git a/template_templ.go b/template_templ.go deleted file mode 100644 index c07ec50..0000000 --- a/template_templ.go +++ /dev/null @@ -1,513 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "context" - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// PageData carries the data the Magazine Bold page templates render. -type PageData struct { - Title string - Slots map[string]string - ThemeMode string - ThemeCSS string - SiteSettings bn.SiteSettingsData - PageMeta bn.PageMeta - StructuredData string - CSSHash string - PageviewNonce string - EngagementConfig bn.EngagementConfig -} - -func parseMagazineBoldPageData(doc map[string]any) PageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok { - title = t - } - - slots := make(map[string]string) - if s, ok := doc["slots"].(map[string]string); ok { - slots = s - } - - themeCSS := "" - if tc, ok := doc["theme_css"].(string); ok { - themeCSS = tc - } - - structuredData := "" - if sd, ok := doc["structured_data"].(string); ok { - structuredData = sd - } - - cssHash := "" - if ch, ok := doc["css_hash"].(string); ok { - cssHash = ch - } - - pageviewNonce := "" - if pn, ok := doc["pageview_nonce"].(string); ok { - pageviewNonce = pn - } - - themeMode := "light" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - siteSettings := bn.ParseSiteSettings(doc) - pageMeta := bn.ParsePageMeta(doc) - engagementConfig := bn.ParseEngagementConfig(doc) - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: siteSettings, - PageMeta: pageMeta, - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: engagementConfig, - } -} - -// mbHead reuses the core head component with the magazine-bold plugin style sheet. -func mbHead(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/magazine-bold/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// MagazineBold — default page template. -// Slots: masthead, main, colophon. -func MagazineBold(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = mbHead(data).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["masthead"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
No content blocks assigned to this page.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["colophon"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// MagazineBoldLanding — issue landing page template. -// Slots: cover, secondary, main, colophon. -func MagazineBoldLanding(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = mbHead(data).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["cover"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["secondary"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
No content blocks assigned to this page.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["colophon"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// MagazineBoldArticle — long-form feature template with deck and pull-quote gutter. -// Slots: masthead, deck, main, colophon. -func MagazineBoldArticle(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = mbHead(data).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["masthead"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["deck"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
No content blocks assigned to this page.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["colophon"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// MagazineBoldFullWidth — edge-to-edge photo-essay template. -// Slots: masthead, main, colophon. -func MagazineBoldFullWidth(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = mbHead(data).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["masthead"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
No content blocks assigned to this page.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["colophon"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// RenderMagazineBold renders the default page. -func RenderMagazineBold(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBold(parseMagazineBoldPageData(doc)) -} - -// RenderMagazineBoldLanding renders the issue-landing page. -func RenderMagazineBoldLanding(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBoldLanding(parseMagazineBoldPageData(doc)) -} - -// RenderMagazineBoldArticle renders the long-form article page. -func RenderMagazineBoldArticle(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBoldArticle(parseMagazineBoldPageData(doc)) -} - -// RenderMagazineBoldFullWidth renders the edge-to-edge photo-essay page. -func RenderMagazineBoldFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return MagazineBoldFullWidth(parseMagazineBoldPageData(doc)) -} - -var _ = templruntime.GeneratedTemplate diff --git a/templates/email/magazine-bold.ninjatpl b/templates/email/magazine-bold.ninjatpl new file mode 100644 index 0000000..36858d1 --- /dev/null +++ b/templates/email/magazine-bold.ninjatpl @@ -0,0 +1,53 @@ + + + + + + + + {{ site_name }} + + + + {% if preview_text %}
{{ preview_text }}
{% endif %} + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/templates/magazine-bold/article.ninjatpl b/templates/magazine-bold/article.ninjatpl new file mode 100644 index 0000000..826048c --- /dev/null +++ b/templates/magazine-bold/article.ninjatpl @@ -0,0 +1,20 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.masthead|safe }}
+
+
+
{{ slots.deck|safe }}
+
+
+
{% if slots.main %}
{{ slots.main|safe }}
{% else %}
No content blocks assigned to this page.
{% endif %}
+
+
+
{{ slots.colophon|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/magazine-bold/default.ninjatpl b/templates/magazine-bold/default.ninjatpl new file mode 100644 index 0000000..3e2326e --- /dev/null +++ b/templates/magazine-bold/default.ninjatpl @@ -0,0 +1,17 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.masthead|safe }}
+
+
+
{% if slots.main %}{{ slots.main|safe }}{% else %}
No content blocks assigned to this page.
{% endif %}
+
+
+
{{ slots.colophon|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/magazine-bold/full-width.ninjatpl b/templates/magazine-bold/full-width.ninjatpl new file mode 100644 index 0000000..e1397b6 --- /dev/null +++ b/templates/magazine-bold/full-width.ninjatpl @@ -0,0 +1,17 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.masthead|safe }}
+
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}
No content blocks assigned to this page.
{% endif %} +
+
+
{{ slots.colophon|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/magazine-bold/landing.ninjatpl b/templates/magazine-bold/landing.ninjatpl new file mode 100644 index 0000000..ba2b6e3 --- /dev/null +++ b/templates/magazine-bold/landing.ninjatpl @@ -0,0 +1,18 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.cover|safe }}
+
+
{{ slots.secondary|safe }}
+
+
+
{% if slots.main %}{{ slots.main|safe }}{% else %}
No content blocks assigned to this page.
{% endif %}
+
+
+
{{ slots.colophon|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/overrides/magazine-bold/button.ninjatpl b/templates/overrides/magazine-bold/button.ninjatpl new file mode 100644 index 0000000..22679fd --- /dev/null +++ b/templates/overrides/magazine-bold/button.ninjatpl @@ -0,0 +1 @@ +{% set _label = label|default:text %}{% set _url = url|default:href %}{% if _label %}{{ _label }}{% endif %} diff --git a/templates/overrides/magazine-bold/heading.ninjatpl b/templates/overrides/magazine-bold/heading.ninjatpl new file mode 100644 index 0000000..3e13cbe --- /dev/null +++ b/templates/overrides/magazine-bold/heading.ninjatpl @@ -0,0 +1 @@ +{% if level|integer == 1 %}

{{ text }}

{% elif level|integer == 3 %}

{{ text }}

{% elif level|integer == 4 %}

{{ text }}

{% elif level|integer == 5 %}
{{ text }}
{% elif level|integer == 6 %}
{{ text }}
{% else %}

{{ text }}

{% endif %} diff --git a/templates/overrides/magazine-bold/image.ninjatpl b/templates/overrides/magazine-bold/image.ninjatpl new file mode 100644 index 0000000..ddbbf9b --- /dev/null +++ b/templates/overrides/magazine-bold/image.ninjatpl @@ -0,0 +1 @@ +{% if src %}
{{ alt }}{% if caption %}
{{ caption }}
{% endif %}
{% endif %} diff --git a/templates/overrides/magazine-bold/text.ninjatpl b/templates/overrides/magazine-bold/text.ninjatpl new file mode 100644 index 0000000..ebe01b4 --- /dev/null +++ b/templates/overrides/magazine-bold/text.ninjatpl @@ -0,0 +1 @@ +
{{ text|safe }}
diff --git a/text_override.go b/text_override.go deleted file mode 100644 index d260fc5..0000000 --- a/text_override.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// TextOverrideBlock renders body text with the Magazine Bold Inter cadence -// and a margin folio. -// -// Built-in text content shape: {"text": "...", "class": "..."} -func TextOverrideBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - class := getString(content, "class") - - var buf bytes.Buffer - _ = mbTextComponent(text, class).Render(ctx, &buf) - return buf.String() -} diff --git a/text_override.templ b/text_override.templ deleted file mode 100644 index cfe45c4..0000000 --- a/text_override.templ +++ /dev/null @@ -1,8 +0,0 @@ -package main - -// mbTextComponent renders a text run in Magazine Bold body cadence (Inter, 16–18px tight leading). -templ mbTextComponent(text string, class string) { -
- @templ.Raw(text) -
-} diff --git a/text_override_templ.go b/text_override_templ.go deleted file mode 100644 index f868bf2..0000000 --- a/text_override_templ.go +++ /dev/null @@ -1,67 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -// mbTextComponent renders a text run in Magazine Bold body cadence (Inter, 16–18px tight leading). -func mbTextComponent(text string, class string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - var templ_7745c5c3_Var2 = []any{"mb-body font-sans", class} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(text).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate