From 5075aa81c9e362e0a81e6430a0285001b67d74d6 Mon Sep 17 00:00:00 2001 From: Alex Dunmow Date: Sat, 4 Jul 2026 14:24:55 +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 Convert the Art Deco theme from a wasm (Go+templ) plugin to a fully codeless .bnp: pure declaration the host runs, no plugin.wasm, no block/core dependency. - blocks/: blocks.yaml (7 fully-qualified art-deco:* keys) + per-block .schema.json (moved from schemas/) + .ninjatpl transcribed byte-for-byte (modulo whitespace) from the templ sources. - templates/art-deco/{default,landing,article,full-width}.ninjatpl — page layouts. - templates/overrides/art-deco/{heading,text,button,image}.ninjatpl. - templates/email/art-deco.ninjatpl. - manifest.yaml (system/page templates, template_overrides, email_wrappers, theme_presets, bundled_fonts, master_pages, css input_css_append) + master_pages.json. - plugin.mod bumped to 0.2.0; [compatibility] block_core dropped (codeless has no core dependency). - Deleted all Go/templ/*_templ.go, go.mod/go.sum; Makefile rewritten to the codeless build/verify/publish targets. Render parity verified against the prior templ output (static pongo2 harness, whitespace-normalised): all 7 blocks, 4 overrides and the email wrapper match. Co-Authored-By: Claude Fable 5 --- Makefile | 40 +- blocks/blocks.yaml | 48 ++ blocks/divider_fan.ninjatpl | 1 + {schemas => blocks}/divider_fan.schema.json | 0 blocks/footer.ninjatpl | 10 + {schemas => blocks}/footer.schema.json | 0 blocks/gallery_fan.ninjatpl | 12 + {schemas => blocks}/gallery_fan.schema.json | 0 blocks/marquee_hero.ninjatpl | 12 + {schemas => blocks}/marquee_hero.schema.json | 0 blocks/menu.ninjatpl | 8 + {schemas => blocks}/menu.schema.json | 0 blocks/press_quote.ninjatpl | 9 + {schemas => blocks}/press_quote.schema.json | 0 blocks/reservation.ninjatpl | 10 + {schemas => blocks}/reservation.schema.json | 0 button_override.go | 41 -- button_override.templ | 36 -- button_override_templ.go | 125 ---- divider_fan.go | 43 -- divider_fan.templ | 26 - divider_fan_templ.go | 88 --- email_wrapper.templ | 178 ----- email_wrapper_templ.go | 463 ------------- embed.go | 58 -- footer.go | 47 -- footer.templ | 59 -- footer_templ.go | 149 ----- gallery_fan.go | 48 -- gallery_fan.templ | 54 -- gallery_fan_templ.go | 169 ----- go.mod | 20 - go.sum | 46 -- heading_override.go | 44 -- heading_override.templ | 69 -- heading_override_templ.go | 311 --------- helpers.go | 59 -- image_override.go | 43 -- image_override.templ | 30 - image_override_templ.go | 124 ---- main.go | 17 - manifest.yaml | 256 ++++++++ marquee_hero.go | 43 -- marquee_hero.templ | 42 -- marquee_hero_templ.go | 152 ----- master_pages.json | 25 + menu.go | 52 -- menu.templ | 50 -- menu_templ.go | 139 ---- plugin.mod | 5 +- press_quote.go | 39 -- press_quote.templ | 39 -- press_quote_helpers.go | 8 - press_quote_templ.go | 114 ---- register.go | 174 ----- registration.go | 25 - reservation.go | 37 -- reservation.templ | 36 -- reservation_templ.go | 136 ---- template.templ | 270 -------- template_templ.go | 607 ------------------ templates/art-deco/article.ninjatpl | 20 + templates/art-deco/default.ninjatpl | 17 + templates/art-deco/full-width.ninjatpl | 15 + templates/art-deco/landing.ninjatpl | 16 + templates/email/art-deco.ninjatpl | 64 ++ templates/overrides/art-deco/button.ninjatpl | 1 + templates/overrides/art-deco/heading.ninjatpl | 1 + templates/overrides/art-deco/image.ninjatpl | 1 + templates/overrides/art-deco/text.ninjatpl | 1 + text_override.go | 26 - text_override.templ | 13 - text_override_templ.go | 67 -- 73 files changed, 546 insertions(+), 4442 deletions(-) create mode 100644 blocks/blocks.yaml create mode 100644 blocks/divider_fan.ninjatpl rename {schemas => blocks}/divider_fan.schema.json (100%) create mode 100644 blocks/footer.ninjatpl rename {schemas => blocks}/footer.schema.json (100%) create mode 100644 blocks/gallery_fan.ninjatpl rename {schemas => blocks}/gallery_fan.schema.json (100%) create mode 100644 blocks/marquee_hero.ninjatpl rename {schemas => blocks}/marquee_hero.schema.json (100%) create mode 100644 blocks/menu.ninjatpl rename {schemas => blocks}/menu.schema.json (100%) create mode 100644 blocks/press_quote.ninjatpl rename {schemas => blocks}/press_quote.schema.json (100%) create mode 100644 blocks/reservation.ninjatpl rename {schemas => blocks}/reservation.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 divider_fan.go delete mode 100644 divider_fan.templ delete mode 100644 divider_fan_templ.go delete mode 100644 email_wrapper.templ delete mode 100644 email_wrapper_templ.go delete mode 100644 embed.go delete mode 100644 footer.go delete mode 100644 footer.templ delete mode 100644 footer_templ.go delete mode 100644 gallery_fan.go delete mode 100644 gallery_fan.templ delete mode 100644 gallery_fan_templ.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 main.go create mode 100644 manifest.yaml delete mode 100644 marquee_hero.go delete mode 100644 marquee_hero.templ delete mode 100644 marquee_hero_templ.go create mode 100644 master_pages.json delete mode 100644 menu.go delete mode 100644 menu.templ delete mode 100644 menu_templ.go delete mode 100644 press_quote.go delete mode 100644 press_quote.templ delete mode 100644 press_quote_helpers.go delete mode 100644 press_quote_templ.go delete mode 100644 register.go delete mode 100644 registration.go delete mode 100644 reservation.go delete mode 100644 reservation.templ delete mode 100644 reservation_templ.go delete mode 100644 template.templ delete mode 100644 template_templ.go create mode 100644 templates/art-deco/article.ninjatpl create mode 100644 templates/art-deco/default.ninjatpl create mode 100644 templates/art-deco/full-width.ninjatpl create mode 100644 templates/art-deco/landing.ninjatpl create mode 100644 templates/email/art-deco.ninjatpl create mode 100644 templates/overrides/art-deco/button.ninjatpl create mode 100644 templates/overrides/art-deco/heading.ninjatpl create mode 100644 templates/overrides/art-deco/image.ninjatpl create mode 100644 templates/overrides/art-deco/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 88d1020..8e3d768 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,27 @@ -# art-deco — build & publish helpers (wasm .bnp workflow) +# art-deco — 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 art-deco-.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 art-deco-.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 := art-deco 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..fea7dd8 --- /dev/null +++ b/blocks/blocks.yaml @@ -0,0 +1,48 @@ +# Art Deco theme block definitions (codeless .bnp, WO-WZ-021). +# Keys are fully qualified (art-deco:) 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: art-deco:reservation + title: Reservation Strip + description: Sticky gold-on-black reservation strip with phone, OpenTable CTA and trading hours. + category: navigation + schema: reservation.schema.json + template: reservation.ninjatpl + - key: art-deco:menu + title: Tasting Menu + description: Symmetric two-column menu card listing courses with description and price. + category: content + schema: menu.schema.json + template: menu.ninjatpl + - key: art-deco:gallery_fan + title: Fan Gallery + description: Mirrored gallery framed by sunburst — collapses to single column under 640px. + category: content + schema: gallery_fan.schema.json + template: gallery_fan.ninjatpl + - key: art-deco:divider_fan + title: Fan Divider + description: Pure-CSS gold geometric divider — sunburst, scallop or ziggurat. + category: layout + schema: divider_fan.schema.json + template: divider_fan.ninjatpl + - key: art-deco:footer + title: Footer + description: Centered Art Deco footer with gold rule, address, reservations email and optional social row. + category: layout + schema: footer.schema.json + template: footer.ninjatpl + - key: art-deco:marquee_hero + title: Marquee Hero + description: Wide hero with stepped ziggurat frame and sunburst overlay. + category: content + schema: marquee_hero.schema.json + template: marquee_hero.ninjatpl + - key: art-deco:press_quote + title: Press Quote + description: Italic Cormorant pull-quote between fan dividers, optional star rating. + category: content + schema: press_quote.schema.json + template: press_quote.ninjatpl diff --git a/blocks/divider_fan.ninjatpl b/blocks/divider_fan.ninjatpl new file mode 100644 index 0000000..7ef1b92 --- /dev/null +++ b/blocks/divider_fan.ninjatpl @@ -0,0 +1 @@ +{% if variant == "scallop" %}{% elif variant == "ziggurat" %}{% else %}{% endif %} diff --git a/schemas/divider_fan.schema.json b/blocks/divider_fan.schema.json similarity index 100% rename from schemas/divider_fan.schema.json rename to blocks/divider_fan.schema.json diff --git a/blocks/footer.ninjatpl b/blocks/footer.ninjatpl new file mode 100644 index 0000000..06a5206 --- /dev/null +++ b/blocks/footer.ninjatpl @@ -0,0 +1,10 @@ +
+
+
+ {% if address %}
{{ address }}
{% endif %} + {% if reservationsEmail %}

{{ reservationsEmail }}

{% endif %} + {% if menuName %}{% endif %} + {% if showSocial != "false" %}
{% endif %} +
+
+
diff --git a/schemas/footer.schema.json b/blocks/footer.schema.json similarity index 100% rename from schemas/footer.schema.json rename to blocks/footer.schema.json diff --git a/blocks/gallery_fan.ninjatpl b/blocks/gallery_fan.ninjatpl new file mode 100644 index 0000000..255b2cd --- /dev/null +++ b/blocks/gallery_fan.ninjatpl @@ -0,0 +1,12 @@ +
+
+
+ +
+ {% if not images %}
Add images to populate the fan gallery.
{% endif %} + {% for img in images %}
{% if img.src %}{{ img.caption }}{% else %}{% endif %}{% if img.caption %}
{{ img.caption }}
{% endif %}
{% endfor %} +
+ +
+
+
diff --git a/schemas/gallery_fan.schema.json b/blocks/gallery_fan.schema.json similarity index 100% rename from schemas/gallery_fan.schema.json rename to blocks/gallery_fan.schema.json diff --git a/blocks/marquee_hero.ninjatpl b/blocks/marquee_hero.ninjatpl new file mode 100644 index 0000000..f471353 --- /dev/null +++ b/blocks/marquee_hero.ninjatpl @@ -0,0 +1,12 @@ +
+ {% if image %}{% endif %} + +
+
+ {% if eyebrow %}

{{ eyebrow }}

{% endif %} + {% if title %}

{{ title }}

{% endif %} + {% if subtitle %}
{{ subtitle|safe }}
{% endif %} + {% if ctaLabel and ctaHref %}{{ ctaLabel }}{% endif %} +
+
+
diff --git a/schemas/marquee_hero.schema.json b/blocks/marquee_hero.schema.json similarity index 100% rename from schemas/marquee_hero.schema.json rename to blocks/marquee_hero.schema.json diff --git a/blocks/menu.ninjatpl b/blocks/menu.ninjatpl new file mode 100644 index 0000000..ccf28a2 --- /dev/null +++ b/blocks/menu.ninjatpl @@ -0,0 +1,8 @@ +
+
+
+ {% if title %}

{{ title }}

{% endif %} + {% if courses %}
    {% for course in courses %}
  • {{ course.name }}

    {% if course.description %}
    {{ course.description|safe }}
    {% endif %}
    {% if course.price %}{{ course.price }}{% endif %}
  • {% endfor %}
{% else %}

Add courses to start composing this menu.

{% endif %} +
+
+
diff --git a/schemas/menu.schema.json b/blocks/menu.schema.json similarity index 100% rename from schemas/menu.schema.json rename to blocks/menu.schema.json diff --git a/blocks/press_quote.ninjatpl b/blocks/press_quote.ninjatpl new file mode 100644 index 0000000..c087de3 --- /dev/null +++ b/blocks/press_quote.ninjatpl @@ -0,0 +1,9 @@ +
+
+ +
{% if quote %}{{ quote|safe }}{% else %}Add a press quote to populate this block.{% endif %}
+ {% if stars|integer > 0 %}
{% if stars|integer >= 1 %}{% else %}{% endif %}{% if stars|integer >= 2 %}{% else %}{% endif %}{% if stars|integer >= 3 %}{% else %}{% endif %}{% if stars|integer >= 4 %}{% else %}{% endif %}{% if stars|integer >= 5 %}{% else %}{% endif %}
{% endif %} + {% if source %}

{{ source }}

{% endif %} + +
+
diff --git a/schemas/press_quote.schema.json b/blocks/press_quote.schema.json similarity index 100% rename from schemas/press_quote.schema.json rename to blocks/press_quote.schema.json diff --git a/blocks/reservation.ninjatpl b/blocks/reservation.ninjatpl new file mode 100644 index 0000000..99c014c --- /dev/null +++ b/blocks/reservation.ninjatpl @@ -0,0 +1,10 @@ +
+
+
+ Reservations + {% if phone %}{{ phone }}{% endif %} +
+ {% if hours %}
{% for line in hours %}{% if not forloop.First %}{% endif %}{{ line }}{% endfor %}
{% endif %} + {% if openTable %}Book a Table{% endif %} +
+
diff --git a/schemas/reservation.schema.json b/blocks/reservation.schema.json similarity index 100% rename from schemas/reservation.schema.json rename to blocks/reservation.schema.json diff --git a/button_override.go b/button_override.go deleted file mode 100644 index 985453e..0000000 --- a/button_override.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// ButtonOverrideData is the typed view for the button override component. -type ButtonOverrideData struct { - Label string - URL string - Variant string -} - -// normaliseButtonVariant returns a known variant or "primary" as default. -func normaliseButtonVariant(v string) string { - switch v { - case "primary", "secondary", "ghost": - return v - default: - return "primary" - } -} - -// ArtDecoButtonBlock overrides the built-in "button" block when the Art Deco theme is active. -// Content: {"label": "...", "url": "...", "variant": "primary|secondary|ghost"} -func ArtDecoButtonBlock(ctx context.Context, content map[string]any) string { - data := ButtonOverrideData{ - Label: getString(content, "label"), - URL: getString(content, "url"), - Variant: normaliseButtonVariant(getString(content, "variant")), - } - - if data.Label == "" { - return "" - } - - var buf bytes.Buffer - _ = artDecoButtonComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/button_override.templ b/button_override.templ deleted file mode 100644 index 525fc26..0000000 --- a/button_override.templ +++ /dev/null @@ -1,36 +0,0 @@ -package main - -// buttonVariantStyle returns inline style overrides per variant. -func buttonVariantStyle(variant string) string { - switch variant { - case "secondary": - return "background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); border-color: hsl(var(--primary));" - case "ghost": - return "background-color: transparent; color: hsl(var(--foreground)); border-color: hsl(var(--primary));" - default: - return "background-color: hsl(var(--foreground)); color: hsl(var(--background)); border-color: hsl(var(--primary));" - } -} - -// artDecoButtonComponent renders the black-pill button with stamped hover state. -templ artDecoButtonComponent(data ButtonOverrideData) { - if data.URL != "" { - - { data.Label } - - } else { - - } -} diff --git a/button_override_templ.go b/button_override_templ.go deleted file mode 100644 index b706533..0000000 --- a/button_override_templ.go +++ /dev/null @@ -1,125 +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" - -// buttonVariantStyle returns inline style overrides per variant. -func buttonVariantStyle(variant string) string { - switch variant { - case "secondary": - return "background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); border-color: hsl(var(--primary));" - case "ghost": - return "background-color: transparent; color: hsl(var(--foreground)); border-color: hsl(var(--primary));" - default: - return "background-color: hsl(var(--foreground)); color: hsl(var(--background)); border-color: hsl(var(--primary));" - } -} - -// artDecoButtonComponent renders the black-pill button with stamped hover state. -func artDecoButtonComponent(data ButtonOverrideData) 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 data.URL != "" { - 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(data.Label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `button_override.templ`, Line: 24, Col: 15} - } - _, 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, 4, "") - 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 - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/divider_fan.go b/divider_fan.go deleted file mode 100644 index 3618cb2..0000000 --- a/divider_fan.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// DividerFanBlockMeta defines the fan divider block. -var DividerFanBlockMeta = blocks.BlockMeta{ - Key: "divider_fan", - Title: "Fan Divider", - Description: "Pure-CSS gold geometric divider — sunburst, scallop or ziggurat.", - Source: "art-deco", -} - -// DividerFanData carries the variant for the divider component. -type DividerFanData struct { - Variant string -} - -// normaliseVariant clamps to the supported set; unknown values fall back to sunburst. -func normaliseVariant(v string) string { - switch v { - case "scallop", "ziggurat": - return v - default: - return "sunburst" - } -} - -// DividerFanBlock renders a CSS-only geometric divider. -// Content: {"variant": "sunburst" | "scallop" | "ziggurat"} -func DividerFanBlock(ctx context.Context, content map[string]any) string { - data := DividerFanData{ - Variant: normaliseVariant(getString(content, "variant")), - } - - var buf bytes.Buffer - _ = dividerFanComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/divider_fan.templ b/divider_fan.templ deleted file mode 100644 index 22859cc..0000000 --- a/divider_fan.templ +++ /dev/null @@ -1,26 +0,0 @@ -package main - -// dividerVariantClass maps the variant to the corresponding utility class. -func dividerVariantClass(variant string) string { - switch variant { - case "scallop": - return "deco-scallop" - case "ziggurat": - return "deco-ziggurat" - default: - return "deco-sunburst" - } -} - -// dividerFanComponent renders a pure-CSS gold geometric divider. -templ dividerFanComponent(data DividerFanData) { - -} diff --git a/divider_fan_templ.go b/divider_fan_templ.go deleted file mode 100644 index 67d4713..0000000 --- a/divider_fan_templ.go +++ /dev/null @@ -1,88 +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" - -// dividerVariantClass maps the variant to the corresponding utility class. -func dividerVariantClass(variant string) string { - switch variant { - case "scallop": - return "deco-scallop" - case "ziggurat": - return "deco-ziggurat" - default: - return "deco-sunburst" - } -} - -// dividerFanComponent renders a pure-CSS gold geometric divider. -func dividerFanComponent(data DividerFanData) 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_Var3 = []any{"h-10 w-full max-w-xl", dividerVariantClass(data.Variant)} - 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, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/email_wrapper.templ b/email_wrapper.templ deleted file mode 100644 index 0dd54ef..0000000 --- a/email_wrapper.templ +++ /dev/null @@ -1,178 +0,0 @@ -package main - -import ( - "bytes" - "context" - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// ArtDecoEmailWrapper wraps body content in the Art Deco email layout: -// ivory background, 600px column, jet-black masthead with flat-gold PNG sunburst, -// Cormorant body, gold hairline above footer, reservation phone postscript. -func ArtDecoEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = artDecoEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// edColor returns a color from the email context or a hex fallback for the named token. -func edColor(value, fallback string) string { - if value != "" { - return value - } - return fallback -} - -// edBg ivory background. -func edBg(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Background, "#f6efe2") -} - -// edCard jet-black masthead surface (uses Foreground as the dark masthead colour). -func edCardDark(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Foreground, "#191510") -} - -// edFg foreground text on the ivory body. -func edFg(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Foreground, "#191510") -} - -// edPrimary champagne-gold accent (used for the hairline and links). -func edPrimary(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Primary, "#c9a14a") -} - -// edMutedFg muted footer text. -func edMutedFg(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.MutedForeground, "#6c5b35") -} - -// edBorder hairline gold border colour. -func edBorder(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Border, "#c9a14a") -} - -// flatGoldSunburstSVG is the inlined data: URI for the flat-gold sunburst image -// used as a fallback for the Outlook masthead (CSS conic-gradient is flattened by Outlook). -// We render via string concatenation so the URL-encoded %xx tokens are not misread as fmt verbs. -func flatGoldSunburstSVG(gold string) string { - g := stripHash(gold) - prefix := "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%2080%22%3E%3Crect%20width%3D%22600%22%20height%3D%2280%22%20fill%3D%22%23191510%22%2F%3E%3Cg%20stroke%3D%22%23" - rays := "%22%20stroke-width%3D%221%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M300%2080%20L%20100%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20180%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20260%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20340%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20420%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20500%2010%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E" - return prefix + g + rays -} - -// stripHash removes a leading '#' if present (defensive for the data URI). -func stripHash(s string) string { - if len(s) > 0 && s[0] == '#' { - return s[1:] - } - return s -} - -// artDecoEmailTemplate renders the Art Deco email wrapper. -templ artDecoEmailTemplate(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 693dc96..0000000 --- a/email_wrapper_templ.go +++ /dev/null @@ -1,463 +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 ( - "bytes" - "context" - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// ArtDecoEmailWrapper wraps body content in the Art Deco email layout: -// ivory background, 600px column, jet-black masthead with flat-gold PNG sunburst, -// Cormorant body, gold hairline above footer, reservation phone postscript. -func ArtDecoEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = artDecoEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// edColor returns a color from the email context or a hex fallback for the named token. -func edColor(value, fallback string) string { - if value != "" { - return value - } - return fallback -} - -// edBg ivory background. -func edBg(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Background, "#f6efe2") -} - -// edCard jet-black masthead surface (uses Foreground as the dark masthead colour). -func edCardDark(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Foreground, "#191510") -} - -// edFg foreground text on the ivory body. -func edFg(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Foreground, "#191510") -} - -// edPrimary champagne-gold accent (used for the hairline and links). -func edPrimary(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Primary, "#c9a14a") -} - -// edMutedFg muted footer text. -func edMutedFg(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.MutedForeground, "#6c5b35") -} - -// edBorder hairline gold border colour. -func edBorder(emailCtx templates.EmailContext) string { - return edColor(emailCtx.Colors.Border, "#c9a14a") -} - -// flatGoldSunburstSVG is the inlined data: URI for the flat-gold sunburst image -// used as a fallback for the Outlook masthead (CSS conic-gradient is flattened by Outlook). -// We render via string concatenation so the URL-encoded %xx tokens are not misread as fmt verbs. -func flatGoldSunburstSVG(gold string) string { - g := stripHash(gold) - prefix := "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20600%2080%22%3E%3Crect%20width%3D%22600%22%20height%3D%2280%22%20fill%3D%22%23191510%22%2F%3E%3Cg%20stroke%3D%22%23" - rays := "%22%20stroke-width%3D%221%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M300%2080%20L%20100%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20180%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20260%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20340%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20420%2010%22%2F%3E%3Cpath%20d%3D%22M300%2080%20L%20500%2010%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E" - return prefix + g + rays -} - -// stripHash removes a leading '#' if present (defensive for the data URI). -func stripHash(s string) string { - if len(s) > 0 && s[0] == '#' { - return s[1:] - } - return s -} - -// artDecoEmailTemplate renders the Art Deco email wrapper. -func artDecoEmailTemplate(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: 94, 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: 113, 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.SiteName != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") - 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: 131, Col: 43} - } - _, 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, 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 - } - 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, 17, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, 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: 149, Col: 42} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) - 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 emailCtx.SiteSettings.SiteURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SiteURL) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 154, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) - 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 - } - } - if emailCtx.SiteSettings.SupportEmail != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "

P.S. Reservations & enquiries: ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SupportEmail) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 160, Col: 82} - } - _, 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, 29, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if emailCtx.UnsubscribeURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "

Unsubscribe

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
") - 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 6526022..0000000 --- a/embed.go +++ /dev/null @@ -1,58 +0,0 @@ -package main - -import ( - "embed" - "io/fs" - "net/http" - - "git.dev.alexdunmow.com/block/core/plugin" -) - -//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 rooted at assets/. -func Assets() fs.FS { - sub, _ := fs.Sub(assetsFS, "assets") - return sub -} - -// Schemas returns the embedded schemas filesystem rooted at schemas/. -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 ([] in this pass). -func BundledFonts() []byte { return fontsData } - -// ThemeCSSManifest exposes the Art Deco utility CSS to the host Tailwind input. -func ThemeCSSManifest() *plugin.CSSManifest { - css, err := assetsFS.ReadFile("assets/style.css") - if err != nil { - return &plugin.CSSManifest{} - } - return &plugin.CSSManifest{ - InputCSSAppend: string(css), - } -} diff --git a/footer.go b/footer.go deleted file mode 100644 index 4442a8b..0000000 --- a/footer.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// FooterBlockMeta defines the Art Deco footer block. -var FooterBlockMeta = blocks.BlockMeta{ - Key: "footer", - Title: "Footer", - Description: "Centered Art Deco footer with gold rule, address, reservations email and optional social row.", - Source: "art-deco", -} - -// FooterData is the typed view for the footer component. -type FooterData struct { - Address string - ReservationsEmail string - ShowSocial bool - MenuName string -} - -// FooterBlock renders the centered Art Deco footer. -// Content: {"address": "...", "reservationsEmail": "...", "showSocial": "true|false", "menuName": "..."} -func FooterBlock(ctx context.Context, content map[string]any) string { - // showSocial is stored as a string select ("true"/"false"); also accept bool for flexibility. - showSocial := true - if b, ok := content["showSocial"].(bool); ok { - showSocial = b - } else if s := getString(content, "showSocial"); s != "" { - showSocial = s != "false" - } - - data := FooterData{ - Address: getString(content, "address"), - ReservationsEmail: getString(content, "reservationsEmail"), - ShowSocial: showSocial, - MenuName: getString(content, "menuName"), - } - - var buf bytes.Buffer - _ = footerComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/footer.templ b/footer.templ deleted file mode 100644 index edf2361..0000000 --- a/footer.templ +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import "strings" - -// addressLines splits a multi-line address into individual lines for centered rendering. -func addressLines(addr string) []string { - if addr == "" { - return nil - } - lines := strings.Split(addr, "\n") - out := make([]string, 0, len(lines)) - for _, line := range lines { - l := strings.TrimSpace(line) - if l != "" { - out = append(out, l) - } - } - return out -} - -// footerComponent renders the centered Art Deco footer. -templ footerComponent(data FooterData) { -
-
-
- if len(addressLines(data.Address)) > 0 { -
- for _, line := range addressLines(data.Address) { -
{ line }
- } -
- } - if data.ReservationsEmail != "" { -

- { data.ReservationsEmail } -

- } - if data.MenuName != "" { - - } - if data.ShowSocial { -
- - - - - -
- } -
-
-
-} diff --git a/footer_templ.go b/footer_templ.go deleted file mode 100644 index 235cf8f..0000000 --- a/footer_templ.go +++ /dev/null @@ -1,149 +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 "strings" - -// addressLines splits a multi-line address into individual lines for centered rendering. -func addressLines(addr string) []string { - if addr == "" { - return nil - } - lines := strings.Split(addr, "\n") - out := make([]string, 0, len(lines)) - for _, line := range lines { - l := strings.TrimSpace(line) - if l != "" { - out = append(out, l) - } - } - return out -} - -// footerComponent renders the centered Art Deco footer. -func footerComponent(data FooterData) 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 len(addressLines(data.Address)) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, line := range addressLines(data.Address) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(line) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `footer.templ`, Line: 29, Col: 17} - } - _, 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, 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 - } - } - if data.ReservationsEmail != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.ReservationsEmail) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `footer.templ`, Line: 35, Col: 109} - } - _, 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 - } - } - if data.MenuName != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.ShowSocial { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
Instagram · Facebook · LinkedIn
") - 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/gallery_fan.go b/gallery_fan.go deleted file mode 100644 index e2ae49c..0000000 --- a/gallery_fan.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// GalleryFanBlockMeta defines the mirrored fan gallery block. -var GalleryFanBlockMeta = blocks.BlockMeta{ - Key: "gallery_fan", - Title: "Fan Gallery", - Description: "Mirrored gallery framed by sunburst — collapses to single column under 640px.", - Source: "art-deco", -} - -// GalleryImage is a single image in the gallery. -type GalleryImage struct { - Src string - Caption string -} - -// GalleryFanData is the typed view for the gallery component. -type GalleryFanData struct { - Images []GalleryImage - Columns int -} - -// GalleryFanBlock renders a mirrored fan gallery. -// Content: {"images": [{"src": "...", "caption": "..."}], "columns": 3} -func GalleryFanBlock(ctx context.Context, content map[string]any) string { - items := getSlice(content, "images") - images := make([]GalleryImage, 0, len(items)) - for _, item := range items { - images = append(images, GalleryImage{ - Src: getString(item, "src"), - Caption: getString(item, "caption"), - }) - } - - cols := getInt(content, "columns", 3) - cols = clampInt(cols, 2, 4) - - var buf bytes.Buffer - _ = galleryFanComponent(GalleryFanData{Images: images, Columns: cols}).Render(ctx, &buf) - return buf.String() -} diff --git a/gallery_fan.templ b/gallery_fan.templ deleted file mode 100644 index 3a3eecb..0000000 --- a/gallery_fan.templ +++ /dev/null @@ -1,54 +0,0 @@ -package main - -// galleryFanGridCols maps the column count to a tailwind grid class with single-column collapse below 640px. -func galleryFanGridCols(cols int) string { - switch cols { - case 2: - return "grid-cols-1 sm:grid-cols-2" - case 4: - return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4" - default: - return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3" - } -} - -// fallbackImage returns a tiny transparent svg data URI used when no image src is supplied. -func fallbackImage() string { - return "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Crect%20width%3D%2232%22%20height%3D%2232%22%20fill%3D%22%23222%22%2F%3E%3C%2Fsvg%3E" -} - -// galleryFanComponent renders the mirrored gallery framed by sunburst rays. -templ galleryFanComponent(data GalleryFanData) { -
-
-
- -
- if len(data.Images) == 0 { -
- Add images to populate the fan gallery. -
- } - for _, img := range data.Images { -
- if img.Src != "" { - { - } else { - - } - if img.Caption != "" { -
- { img.Caption } -
- } -
- } -
- -
-
-
-} diff --git a/gallery_fan_templ.go b/gallery_fan_templ.go deleted file mode 100644 index 385f494..0000000 --- a/gallery_fan_templ.go +++ /dev/null @@ -1,169 +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" - -// galleryFanGridCols maps the column count to a tailwind grid class with single-column collapse below 640px. -func galleryFanGridCols(cols int) string { - switch cols { - case 2: - return "grid-cols-1 sm:grid-cols-2" - case 4: - return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4" - default: - return "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3" - } -} - -// fallbackImage returns a tiny transparent svg data URI used when no image src is supplied. -func fallbackImage() string { - return "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Crect%20width%3D%2232%22%20height%3D%2232%22%20fill%3D%22%23222%22%2F%3E%3C%2Fsvg%3E" -} - -// galleryFanComponent renders the mirrored gallery framed by sunburst rays. -func galleryFanComponent(data GalleryFanData) 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 = []any{"grid gap-4 pt-12", galleryFanGridCols(data.Columns)} - 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, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(data.Images) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
Add images to populate the fan gallery.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - for _, img := range data.Images { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if img.Src != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\"") ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"\" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if img.Caption != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(img.Caption) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `gallery_fan.templ`, Line: 44, Col: 22} - } - _, 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, 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/go.mod b/go.mod deleted file mode 100644 index f4260c9..0000000 --- a/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module git.dev.alexdunmow.com/block/themes/art-deco - -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 985e1bb..0000000 --- a/heading_override.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "bytes" - "context" - "strconv" -) - -// parseHeadingLevel reads "level" from a content map, defaulting to 2 and clamping to 1..6. -func parseHeadingLevel(content map[string]any) int { - if v, ok := content["level"].(float64); ok { - return clampInt(int(v), 1, 6) - } - if v, ok := content["level"].(int); ok { - return clampInt(v, 1, 6) - } - if v, ok := content["level"].(string); ok { - if i, err := strconv.Atoi(v); err == nil { - return clampInt(i, 1, 6) - } - } - return 2 -} - -// ArtDecoHeadingBlock overrides the built-in "heading" block when the Art Deco theme is active. -// Content: {"text": "...", "level": 1-6, "textClass": "optional-utility-classes"} -func ArtDecoHeadingBlock(ctx context.Context, content map[string]any) string { - data := HeadingData{ - Text: getString(content, "text"), - Level: parseHeadingLevel(content), - ExtraCls: getString(content, "textClass"), - } - - var buf bytes.Buffer - _ = artDecoHeadingComponent(data).Render(ctx, &buf) - return buf.String() -} - -// HeadingData is the typed view for the heading override component. -type HeadingData struct { - Text string - Level int - ExtraCls string -} diff --git a/heading_override.templ b/heading_override.templ deleted file mode 100644 index 553cbb3..0000000 --- a/heading_override.templ +++ /dev/null @@ -1,69 +0,0 @@ -package main - -// headingSizeClass returns the responsive size utility for a given heading level. -func headingSizeClass(level int) string { - switch level { - case 1: - return "text-4xl md:text-5xl" - case 2: - return "text-3xl md:text-4xl" - case 3: - return "text-2xl md:text-3xl" - case 4: - return "text-xl md:text-2xl" - case 5: - return "text-lg md:text-xl" - case 6: - return "text-base md:text-lg" - default: - return "text-3xl md:text-4xl" - } -} - -// artDecoHeadingComponent renders an Art Deco heading with caps tracking and hairline gold underline. -templ artDecoHeadingComponent(data HeadingData) { - switch data.Level { - case 1: -

{ data.Text }

- case 2: -

{ data.Text }

- case 3: -

{ data.Text }

- case 4: -

{ data.Text }

- case 5: -
{ data.Text }
- case 6: -
{ data.Text }
- default: -

{ data.Text }

- } -} diff --git a/heading_override_templ.go b/heading_override_templ.go deleted file mode 100644 index cd23d5a..0000000 --- a/heading_override_templ.go +++ /dev/null @@ -1,311 +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" - -// headingSizeClass returns the responsive size utility for a given heading level. -func headingSizeClass(level int) string { - switch level { - case 1: - return "text-4xl md:text-5xl" - case 2: - return "text-3xl md:text-4xl" - case 3: - return "text-2xl md:text-3xl" - case 4: - return "text-xl md:text-2xl" - case 5: - return "text-lg md:text-xl" - case 6: - return "text-base md:text-lg" - default: - return "text-3xl md:text-4xl" - } -} - -// artDecoHeadingComponent renders an Art Deco heading with caps tracking and hairline gold underline. -func artDecoHeadingComponent(data HeadingData) 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 data.Level { - case 1: - var templ_7745c5c3_Var2 = []any{"deco-caps deco-underline", headingSizeClass(1), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 31, Col: 15} - } - _, 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{"deco-caps deco-underline", headingSizeClass(2), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 37, Col: 15} - } - _, 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{"deco-caps deco-underline", headingSizeClass(3), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 43, Col: 15} - } - _, 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{"deco-caps deco-underline", headingSizeClass(4), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 49, Col: 15} - } - _, 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{"deco-caps deco-underline", headingSizeClass(5), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 55, Col: 15} - } - _, 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{"deco-caps deco-underline", headingSizeClass(6), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 61, Col: 15} - } - _, 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{"deco-caps deco-underline", headingSizeClass(2), data.ExtraCls} - 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(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 67, Col: 15} - } - _, 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 195b329..0000000 --- a/helpers.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -// getString extracts a string value from a 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 a 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 -} - -// getSlice extracts a slice of maps from a content map. -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 -} - -// getStringSlice extracts a slice of strings from a content map. -func getStringSlice(content map[string]any, key string) []string { - if v, ok := content[key].([]any); ok { - result := make([]string, 0, len(v)) - for _, item := range v { - if s, ok := item.(string); ok { - result = append(result, s) - } - } - return result - } - return nil -} - -// clampInt clamps an int into [min, max] inclusive. -func clampInt(v, min, max int) int { - if v < min { - return min - } - if v > max { - return max - } - return v -} diff --git a/image_override.go b/image_override.go deleted file mode 100644 index 6b8932f..0000000 --- a/image_override.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// ImageOverrideData is the typed view for the image override component. -type ImageOverrideData struct { - Src string - Alt string - Caption string - Frame string -} - -// normaliseImageFrame clamps the frame option to the supported set. -func normaliseImageFrame(v string) string { - switch v { - case "stepped", "scallop", "plain": - return v - default: - return "stepped" - } -} - -// ArtDecoImageBlock overrides the built-in "image" block when the Art Deco theme is active. -// Content: {"src": "...", "alt": "...", "caption": "...", "frame": "stepped|scallop|plain"} -func ArtDecoImageBlock(ctx context.Context, content map[string]any) string { - data := ImageOverrideData{ - Src: getString(content, "src"), - Alt: getString(content, "alt"), - Caption: getString(content, "caption"), - Frame: normaliseImageFrame(getString(content, "frame")), - } - - if data.Src == "" { - data.Src = fallbackImage() - } - - var buf bytes.Buffer - _ = artDecoImageComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/image_override.templ b/image_override.templ deleted file mode 100644 index f8005f3..0000000 --- a/image_override.templ +++ /dev/null @@ -1,30 +0,0 @@ -package main - -// imageFrameClass returns the utility class for an image frame option. -func imageFrameClass(frame string) string { - switch frame { - case "scallop": - return "deco-scallop" - case "plain": - return "" - default: - return "deco-step" - } -} - -// artDecoImageComponent renders an image wrapped in the stepped ziggurat frame option. -templ artDecoImageComponent(data ImageOverrideData) { -
-
- { -
- if data.Caption != "" { -
- { data.Caption } -
- } -
-} diff --git a/image_override_templ.go b/image_override_templ.go deleted file mode 100644 index 23e1d59..0000000 --- a/image_override_templ.go +++ /dev/null @@ -1,124 +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" - -// imageFrameClass returns the utility class for an image frame option. -func imageFrameClass(frame string) string { - switch frame { - case "scallop": - return "deco-scallop" - case "plain": - return "" - default: - return "deco-step" - } -} - -// artDecoImageComponent renders an image wrapped in the stepped ziggurat frame option. -func artDecoImageComponent(data ImageOverrideData) 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 = []any{imageFrameClass(data.Frame)} - 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, 2, "
\"")
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Caption != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(data.Caption) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `image_override.templ`, Line: 26, Col: 18} - } - _, 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, 7, "
") - 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 - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/main.go b/main.go deleted file mode 100644 index 895d149..0000000 --- a/main.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build wasip1 - -// Package main compiles the Art Deco 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..340dbdb --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,256 @@ +# Art Deco theme — codeless .bnp manifest (WO-WZ-021 Phase B). +# 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: art-deco + title: Art Deco + description: "Luxury Art Deco theme with champagne gold gradients, jet black, ivory and geometric fan motifs for hotels, fine dining, weddings and jewellers." + +page_templates: + - system: art-deco + key: default + title: Default + description: "Centered symmetric layout with gold rule header and footer." + slots: [header, main, footer] + - system: art-deco + key: landing + title: Marquee Landing + description: "Wide hero with sunburst overlay, reservation strip, CTA." + slots: [marquee, main, cta, footer] + - system: art-deco + key: article + title: Editorial + description: "Narrow editorial column for press, menus and stories." + slots: [header, main, aside, footer] + - system: art-deco + key: full-width + title: Grand Ballroom + description: "Edge-to-edge gallery layout for venues and lookbooks." + slots: [header, main, footer] + +template_overrides: + - { template: art-deco, block: heading } + - { template: art-deco, block: text } + - { template: art-deco, block: button } + - { template: art-deco, block: image } + +email_wrappers: + - art-deco + +css: + input_css_append: | + /* Art Deco theme — utility CSS for foil, frames, fans and grain. + * + * Color is always consumed via hsl(var(--token)) — the tokens carry HSL triples. + * Font families always come from var(--font-heading|body|mono, ). + */ + + @layer utilities { + /* deco-rule — hairline gold rule, 1px ascending to 2px on accent lines. */ + .deco-rule { + border: none; + border-top: 1px solid hsl(var(--primary)); + margin: 0; + } + .deco-rule-thick { + border: none; + border-top: 2px solid hsl(var(--primary)); + margin: 0; + } + + /* deco-frame — stepped ziggurat frame, layered borders + clipped corners. */ + .deco-frame { + position: relative; + border: 1px solid hsl(var(--primary)); + padding: 1.25rem; + } + .deco-frame::before, + .deco-frame::after { + content: ""; + position: absolute; + left: -6px; + right: -6px; + height: 4px; + background: hsl(var(--primary)); + opacity: 0.85; + } + .deco-frame::before { top: -6px; } + .deco-frame::after { bottom: -6px; } + + /* deco-step — stepped corner mask suitable for image frames. */ + .deco-step { + position: relative; + padding: 4px; + background: + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) top left / 14px 1px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) top left / 1px 14px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) top right / 14px 1px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) top right / 1px 14px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) bottom left / 14px 1px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) bottom left / 1px 14px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) bottom right / 14px 1px no-repeat, + linear-gradient(hsl(var(--primary)), hsl(var(--primary))) bottom right / 1px 14px no-repeat; + } + .deco-step > * { + display: block; + width: 100%; + height: 100%; + } + + /* deco-grain — 3% film-grain noise, dark surfaces only. */ + .deco-grain { + position: relative; + isolation: isolate; + } + .deco-grain::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + pointer-events: none; + opacity: 0.03; + background-image: + repeating-radial-gradient(circle at 17% 23%, hsl(var(--foreground)) 0 1px, transparent 1px 3px), + repeating-radial-gradient(circle at 73% 61%, hsl(var(--foreground)) 0 1px, transparent 1px 3px); + mix-blend-mode: overlay; + } + + /* deco-foil — inset gold "stamp" shadow used on hover states. */ + .deco-foil { + box-shadow: + inset 0 0 0 1px hsl(var(--primary)), + inset 0 1px 0 hsl(var(--primary) / 0.6), + inset 0 -1px 0 hsl(var(--primary) / 0.3); + } + + /* deco-sunburst — conic-gradient sunburst rays. Used by divider_fan & marquee_hero. */ + .deco-sunburst { + background-image: + conic-gradient( + from 180deg at 50% 100%, + transparent 0deg, + hsl(var(--primary) / 0.7) 5deg, + transparent 10deg, + transparent 20deg, + hsl(var(--primary) / 0.55) 25deg, + transparent 30deg, + transparent 40deg, + hsl(var(--primary) / 0.7) 45deg, + transparent 50deg, + transparent 60deg, + hsl(var(--primary) / 0.55) 65deg, + transparent 70deg, + transparent 80deg, + hsl(var(--primary) / 0.7) 85deg, + transparent 90deg, + transparent 100deg, + hsl(var(--primary) / 0.55) 105deg, + transparent 110deg, + transparent 120deg, + hsl(var(--primary) / 0.7) 125deg, + transparent 130deg, + transparent 140deg, + hsl(var(--primary) / 0.55) 145deg, + transparent 150deg, + transparent 160deg, + hsl(var(--primary) / 0.7) 165deg, + transparent 170deg, + transparent 180deg + ); + } + + /* deco-scallop — scalloped fan crest via radial gradient. */ + .deco-scallop { + background-image: + radial-gradient(circle at 50% 100%, hsl(var(--primary) / 0.7) 0 2px, transparent 3px), + repeating-linear-gradient( + to right, + transparent 0, + transparent 12px, + hsl(var(--primary) / 0.55) 12px, + hsl(var(--primary) / 0.55) 13px, + transparent 13px, + transparent 24px + ); + } + + /* deco-ziggurat — stepped ziggurat divider stripes. */ + .deco-ziggurat { + background-image: + linear-gradient(to bottom, transparent 0 30%, hsl(var(--primary)) 30% 32%, transparent 32% 50%, hsl(var(--primary)) 50% 52%, transparent 52% 70%, hsl(var(--primary)) 70% 72%, transparent 72% 100%); + } + + /* deco-caps — caps tracking helper for Italiana display headings. */ + .deco-caps { + text-transform: uppercase; + letter-spacing: 0.18em; + } + + /* deco-dropcap — classical italic dropcap on first paragraph. */ + .deco-dropcap[data-deco-dropcap]::first-letter { + font-family: var(--font-body, "Cormorant Garamond", "Cormorant", Georgia, serif); + font-style: italic; + font-size: 3.2em; + line-height: 0.95; + float: left; + padding: 0.05em 0.12em 0 0; + color: hsl(var(--primary)); + } + + /* deco-underline — hairline gold underline on headings. */ + .deco-underline { + position: relative; + padding-bottom: 0.35em; + } + .deco-underline::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 1px; + background: hsl(var(--primary)); + } + + /* deco-pill — black pill button base for the button override. */ + .deco-pill { + border-radius: 9999px; + border-width: 1px; + border-style: solid; + border-color: hsl(var(--primary)); + background-color: hsl(var(--foreground)); + color: hsl(var(--background)); + padding: 0.65rem 1.6rem; + text-transform: uppercase; + letter-spacing: 0.18em; + font-size: 0.85rem; + transition: box-shadow 200ms ease, background-color 200ms ease; + } + .deco-pill:hover, + .deco-pill:focus-visible { + box-shadow: + inset 0 0 0 1px hsl(var(--primary)), + inset 0 1px 0 hsl(var(--primary) / 0.6), + inset 0 -1px 0 hsl(var(--primary) / 0.4); + } + .deco-pill:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 3px; + } + + /* deco-link — gold underline link state. */ + .deco-link { + color: hsl(var(--primary)); + text-decoration: none; + border-bottom: 1px solid hsl(var(--primary)); + transition: color 200ms ease, border-color 200ms ease; + } + .deco-link:hover, + .deco-link:focus-visible { + color: hsl(var(--accent)); + border-bottom-color: hsl(var(--accent)); + } + } diff --git a/marquee_hero.go b/marquee_hero.go deleted file mode 100644 index 4e374c1..0000000 --- a/marquee_hero.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// MarqueeHeroBlockMeta defines the marquee hero block. -var MarqueeHeroBlockMeta = blocks.BlockMeta{ - Key: "marquee_hero", - Title: "Marquee Hero", - Description: "Wide hero with stepped ziggurat frame and sunburst overlay.", - Source: "art-deco", -} - -// MarqueeHeroData is the typed view for the marquee hero component. -type MarqueeHeroData struct { - Eyebrow string - Title string - Subtitle string - CTALabel string - CTAHref string - Image string -} - -// MarqueeHeroBlock renders the wide hero with stepped frame and sunburst overlay. -// Content: {"eyebrow": "...", "title": "...", "subtitle": "...", "ctaLabel": "...", "ctaHref": "...", "image": "..."} -func MarqueeHeroBlock(ctx context.Context, content map[string]any) string { - data := MarqueeHeroData{ - Eyebrow: getString(content, "eyebrow"), - Title: getString(content, "title"), - Subtitle: getString(content, "subtitle"), - CTALabel: getString(content, "ctaLabel"), - CTAHref: getString(content, "ctaHref"), - Image: getString(content, "image"), - } - - var buf bytes.Buffer - _ = marqueeHeroComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/marquee_hero.templ b/marquee_hero.templ deleted file mode 100644 index ee4a833..0000000 --- a/marquee_hero.templ +++ /dev/null @@ -1,42 +0,0 @@ -package main - -// marqueeHeroComponent renders the wide hero with stepped ziggurat frame and sunburst overlay. -templ marqueeHeroComponent(data MarqueeHeroData) { -
- if data.Image != "" { - - } - -
-
- if data.Eyebrow != "" { -

{ data.Eyebrow }

- } - if data.Title != "" { -

- { data.Title } -

- } - if data.Subtitle != "" { -
- @templ.Raw(data.Subtitle) -
- } - if data.CTALabel != "" && data.CTAHref != "" { - - { data.CTALabel } - - } -
-
-
-} diff --git a/marquee_hero_templ.go b/marquee_hero_templ.go deleted file mode 100644 index 089d3df..0000000 --- a/marquee_hero_templ.go +++ /dev/null @@ -1,152 +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" - -// marqueeHeroComponent renders the wide hero with stepped ziggurat frame and sunburst overlay. -func marqueeHeroComponent(data MarqueeHeroData) 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.Image != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
\"\"
") - 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.Eyebrow != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.Eyebrow) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marquee_hero.templ`, Line: 16, Col: 89} - } - _, 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, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.Title != "" { - 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.Title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marquee_hero.templ`, Line: 23, Col: 18} - } - _, 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 - } - } - if data.Subtitle != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Subtitle).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 - } - } - if data.CTALabel != "" && data.CTAHref != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(data.CTALabel) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `marquee_hero.templ`, Line: 36, Col: 21} - } - _, 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, 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/master_pages.json b/master_pages.json new file mode 100644 index 0000000..6d64ed4 --- /dev/null +++ b/master_pages.json @@ -0,0 +1,25 @@ +[ + { + "key": "art-deco:default-master", + "title": "Art Deco Default Master", + "page_templates": ["default", "article"], + "blocks": [ + { "block_key": "navbar", "title": "Brass Navigation", "content": { "menuName": "main" }, "slot": "header", "sort_order": 0 }, + { "block_key": "art-deco:divider_fan", "title": "Header Fan Divider", "content": { "variant": "sunburst" }, "slot": "header", "sort_order": 1 }, + { "block_key": "slot", "title": "Main Content", "content": { "slotName": "main", "placeholder": "Page content" }, "slot": "main", "sort_order": 0 }, + { "block_key": "art-deco:footer", "title": "Site Footer", "content": { "address": "", "reservationsEmail": "", "showSocial": "true" }, "slot": "footer", "sort_order": 0 } + ] + }, + { + "key": "art-deco:marquee-master", + "title": "Art Deco Marquee Master", + "page_templates": ["landing", "full-width"], + "blocks": [ + { "block_key": "navbar", "title": "Brass Navigation", "content": { "menuName": "main" }, "slot": "marquee", "sort_order": 0 }, + { "block_key": "art-deco:reservation", "title": "Reservation Strip", "content": { "phone": "", "openTable": "" }, "slot": "marquee", "sort_order": 1 }, + { "block_key": "slot", "title": "Main Content", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "art-deco:divider_fan", "title": "CTA Fan Divider", "content": { "variant": "scallop" }, "slot": "cta", "sort_order": 0 }, + { "block_key": "art-deco:footer", "title": "Site Footer", "content": { "showSocial": "true" }, "slot": "footer", "sort_order": 0 } + ] + } +] diff --git a/menu.go b/menu.go deleted file mode 100644 index 9560d12..0000000 --- a/menu.go +++ /dev/null @@ -1,52 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// MenuBlockMeta defines the tasting menu block. -var MenuBlockMeta = blocks.BlockMeta{ - Key: "menu", - Title: "Tasting Menu", - Description: "Symmetric two-column menu card listing courses with description and price.", - Source: "art-deco", -} - -// MenuCourse is a single course on the menu. -type MenuCourse struct { - Name string - Description string - Price string -} - -// MenuData is the typed view for the menu component. -type MenuData struct { - Title string - Courses []MenuCourse -} - -// MenuBlock renders a tasting menu card. -// Content: {"title": "...", "courses": [{"name": "...", "description": "...", "price": "..."}]} -func MenuBlock(ctx context.Context, content map[string]any) string { - items := getSlice(content, "courses") - courses := make([]MenuCourse, 0, len(items)) - for _, item := range items { - courses = append(courses, MenuCourse{ - Name: getString(item, "name"), - Description: getString(item, "description"), - Price: getString(item, "price"), - }) - } - - data := MenuData{ - Title: getString(content, "title"), - Courses: courses, - } - - var buf bytes.Buffer - _ = menuComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/menu.templ b/menu.templ deleted file mode 100644 index 31a9a7d..0000000 --- a/menu.templ +++ /dev/null @@ -1,50 +0,0 @@ -package main - -// menuComponent renders the symmetric two-column menu card. -templ menuComponent(data MenuData) { -
-
-
- if data.Title != "" { -

- { data.Title } -

- } - if len(data.Courses) == 0 { -

Add courses to start composing this menu.

- } else { -
    - for _, course := range data.Courses { -
  • -
    -

    - { course.Name } -

    - if course.Description != "" { -
    - @templ.Raw(course.Description) -
    - } -
    - if course.Price != "" { - - { course.Price } - - } -
  • - } -
- } -
-
-
-} diff --git a/menu_templ.go b/menu_templ.go deleted file mode 100644 index 3373896..0000000 --- a/menu_templ.go +++ /dev/null @@ -1,139 +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" - -// menuComponent renders the symmetric two-column menu card. -func menuComponent(data MenuData) 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: `menu.templ`, Line: 13, Col: 18} - } - _, 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.Courses) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

Add courses to start composing this menu.

") - 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 _, course := range data.Courses { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
  • ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(course.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `menu.templ`, Line: 27, Col: 23} - } - _, 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, 7, "

    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if course.Description != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(course.Description).Render(ctx, templ_7745c5c3_Buffer) - 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 - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if course.Price != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(course.Price) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `menu.templ`, Line: 40, Col: 24} - } - _, 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, 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 bc0981a..236b79f 100644 --- a/plugin.mod +++ b/plugin.mod @@ -2,11 +2,8 @@ name = "art-deco" display_name = "Art Deco" scope = "@themes" -version = "0.1.2" +version = "0.2.0" description = "Luxury Art Deco theme with champagne gold gradients, jet black, ivory and geometric fan motifs for hotels, fine dining, weddings and jewellers." kind = "theme" categories = ["templates"] tags = ["luxury", "gold", "hospitality", "hotel", "wedding", "jewellery", "vintage", "glam", "fine-dining"] - -[compatibility] -block_core = ">=0.15.0 <0.16.0" diff --git a/press_quote.go b/press_quote.go deleted file mode 100644 index 609495d..0000000 --- a/press_quote.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// PressQuoteBlockMeta defines the press quote block. -var PressQuoteBlockMeta = blocks.BlockMeta{ - Key: "press_quote", - Title: "Press Quote", - Description: "Italic Cormorant pull-quote between fan dividers, optional star rating.", - Source: "art-deco", -} - -// PressQuoteData is the typed view for the press quote component. -type PressQuoteData struct { - Quote string - Source string - Stars int -} - -// PressQuoteBlock renders the italic pull-quote framed by fan dividers. -// Content: {"quote": "...", "source": "...", "stars": 5} -func PressQuoteBlock(ctx context.Context, content map[string]any) string { - stars := clampInt(getInt(content, "stars", 0), 0, 5) - - data := PressQuoteData{ - Quote: getString(content, "quote"), - Source: getString(content, "source"), - Stars: stars, - } - - var buf bytes.Buffer - _ = pressQuoteComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/press_quote.templ b/press_quote.templ deleted file mode 100644 index 967a463..0000000 --- a/press_quote.templ +++ /dev/null @@ -1,39 +0,0 @@ -package main - -// pressQuoteComponent renders the italic Cormorant pull-quote between fan dividers. -templ pressQuoteComponent(data PressQuoteData) { -
-
- -
- if data.Quote != "" { - @templ.Raw(data.Quote) - } else { - Add a press quote to populate this block. - } -
- if data.Stars > 0 { -
- for i := 0; i < data.Stars; i++ { - - } - for i := data.Stars; i < 5; i++ { - - } -
- } - if data.Source != "" { -

- { data.Source } -

- } - -
-
-} diff --git a/press_quote_helpers.go b/press_quote_helpers.go deleted file mode 100644 index 3939570..0000000 --- a/press_quote_helpers.go +++ /dev/null @@ -1,8 +0,0 @@ -package main - -import "strconv" - -// starsAttr renders an int into a stable data-stars attribute string. -func starsAttr(n int) string { - return strconv.Itoa(n) -} diff --git a/press_quote_templ.go b/press_quote_templ.go deleted file mode 100644 index e5bc4e8..0000000 --- a/press_quote_templ.go +++ /dev/null @@ -1,114 +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" - -// pressQuoteComponent renders the italic Cormorant pull-quote between fan dividers. -func pressQuoteComponent(data PressQuoteData) 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.Quote != "" { - templ_7745c5c3_Err = templ.Raw(data.Quote).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "Add a press quote to populate this block.") - 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.Stars > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for i := 0; i < data.Stars; i++ { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - for i := data.Stars; i < 5; i++ { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - 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 - } - } - if data.Source != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.Source) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `press_quote.templ`, Line: 33, Col: 18} - } - _, 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, 10, "

") - 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/register.go b/register.go deleted file mode 100644 index e0a56e6..0000000 --- a/register.go +++ /dev/null @@ -1,174 +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 into a 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 wires up the Art Deco system template, its page templates, blocks, -// template overrides and email wrapper. -func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - // Schemas must be loaded BEFORE any br.Register call so block schemas bind. - if err := br.LoadSchemasFromFS(Schemas()); err != nil { - return err - } - - // System template metadata. - tr.RegisterSystemTemplate(templates.SystemTemplateMeta{ - Key: "art-deco", - Title: "Art Deco", - Description: "Luxury Art Deco theme with champagne gold gradients, jet black, ivory and geometric fan motifs for hotels, fine dining, weddings and jewellers.", - }) - - // Page templates. - if err := tr.RegisterPageTemplate("art-deco", templates.PageTemplateMeta{ - Key: "default", - Title: "Default", - Description: "Centered symmetric layout with gold rule header and footer.", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderArtDecoDefault)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("art-deco", templates.PageTemplateMeta{ - Key: "landing", - Title: "Marquee Landing", - Description: "Wide hero with sunburst overlay, reservation strip, CTA.", - Slots: []string{"marquee", "main", "cta", "footer"}, - }, wrap(RenderArtDecoLanding)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("art-deco", templates.PageTemplateMeta{ - Key: "article", - Title: "Editorial", - Description: "Narrow editorial column for press, menus and stories.", - Slots: []string{"header", "main", "aside", "footer"}, - }, wrap(RenderArtDecoArticle)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("art-deco", templates.PageTemplateMeta{ - Key: "full-width", - Title: "Grand Ballroom", - Description: "Edge-to-edge gallery layout for venues and lookbooks.", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderArtDecoFullWidth)); err != nil { - return err - } - - // Theme-specific blocks. - br.Register(ReservationBlockMeta, ReservationBlock) - br.Register(MenuBlockMeta, MenuBlock) - br.Register(GalleryFanBlockMeta, GalleryFanBlock) - br.Register(DividerFanBlockMeta, DividerFanBlock) - br.Register(FooterBlockMeta, FooterBlock) - br.Register(MarqueeHeroBlockMeta, MarqueeHeroBlock) - br.Register(PressQuoteBlockMeta, PressQuoteBlock) - - // Template overrides — active only while the Art Deco system template is selected. - br.RegisterTemplateOverride("art-deco", "heading", ArtDecoHeadingBlock) - br.RegisterTemplateOverride("art-deco", "text", ArtDecoTextBlock) - br.RegisterTemplateOverride("art-deco", "button", ArtDecoButtonBlock) - br.RegisterTemplateOverride("art-deco", "image", ArtDecoImageBlock) - - // Branded email wrapper. - tr.RegisterEmailWrapper("art-deco", ArtDecoEmailWrapper) - - return nil -} - -// DefaultMasterPages returns the master pages provisioned the first time the plugin loads. -func DefaultMasterPages() []plugin.MasterPageDefinition { - return []plugin.MasterPageDefinition{ - { - Key: "art-deco:default-master", - Title: "Art Deco Default Master", - PageTemplates: []string{"default", "article"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Brass Navigation", - Content: map[string]any{"menuName": "main"}, - Slot: "header", - SortOrder: 0, - }, - { - BlockKey: "art-deco:divider_fan", - Title: "Header Fan Divider", - Content: map[string]any{"variant": "sunburst"}, - Slot: "header", - SortOrder: 1, - }, - { - BlockKey: "slot", - Title: "Main Content", - Content: map[string]any{"slotName": "main", "placeholder": "Page content"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "art-deco:footer", - Title: "Site Footer", - Content: map[string]any{"address": "", "reservationsEmail": "", "showSocial": "true"}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - { - Key: "art-deco:marquee-master", - Title: "Art Deco Marquee Master", - PageTemplates: []string{"landing", "full-width"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Brass Navigation", - Content: map[string]any{"menuName": "main"}, - Slot: "marquee", - SortOrder: 0, - }, - { - BlockKey: "art-deco:reservation", - Title: "Reservation Strip", - Content: map[string]any{"phone": "", "openTable": ""}, - Slot: "marquee", - SortOrder: 1, - }, - { - BlockKey: "slot", - Title: "Main Content", - Content: map[string]any{"slotName": "main"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "art-deco:divider_fan", - Title: "CTA Fan Divider", - Content: map[string]any{"variant": "scallop"}, - Slot: "cta", - SortOrder: 0, - }, - { - BlockKey: "art-deco:footer", - Title: "Site Footer", - Content: map[string]any{"showSocial": "true"}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - } -} diff --git a/registration.go b/registration.go deleted file mode 100644 index 1a78bf9..0000000 --- a/registration.go +++ /dev/null @@ -1,25 +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 Art Deco theme. -var Registration = plugin.PluginRegistration{ - Name: "art-deco", - 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() }, -} diff --git a/reservation.go b/reservation.go deleted file mode 100644 index 822f317..0000000 --- a/reservation.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ReservationBlockMeta defines the reservation strip block. -var ReservationBlockMeta = blocks.BlockMeta{ - Key: "reservation", - Title: "Reservation Strip", - Description: "Sticky gold-on-black reservation strip with phone, OpenTable CTA and trading hours.", - Source: "art-deco", -} - -// ReservationData is the typed view used by the templ component. -type ReservationData struct { - Phone string - OpenTable string - Hours []string -} - -// ReservationBlock renders a reservation strip. -// Content: {"phone": "...", "openTable": "...", "hours": ["Tue–Sat · 6pm–late", ...]} -func ReservationBlock(ctx context.Context, content map[string]any) string { - data := ReservationData{ - Phone: getString(content, "phone"), - OpenTable: getString(content, "openTable"), - Hours: getStringSlice(content, "hours"), - } - - var buf bytes.Buffer - _ = reservationComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/reservation.templ b/reservation.templ deleted file mode 100644 index dec70c3..0000000 --- a/reservation.templ +++ /dev/null @@ -1,36 +0,0 @@ -package main - -// reservationComponent renders the sticky reservation strip. -// Empty inputs render a shell with a "Reservations" label so the strip is never blank. -templ reservationComponent(data ReservationData) { -
-
-
- Reservations - if data.Phone != "" { - - { data.Phone } - } -
- if len(data.Hours) > 0 { -
- for i, line := range data.Hours { - if i > 0 { - - } - { line } - } -
- } - if data.OpenTable != "" { - - Book a Table - - } -
-
-} diff --git a/reservation_templ.go b/reservation_templ.go deleted file mode 100644 index ed12eb8..0000000 --- a/reservation_templ.go +++ /dev/null @@ -1,136 +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" - -// reservationComponent renders the sticky reservation strip. -// Empty inputs render a shell with a "Reservations" label so the strip is never blank. -func reservationComponent(data ReservationData) 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 len(data.Hours) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for i, line := range data.Hours { - if i > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "·") - 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 - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(line) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `reservation.templ`, Line: 25, Col: 18} - } - _, 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, 9, "") - 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 data.OpenTable != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "Book a Table") - 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/template.templ b/template.templ deleted file mode 100644 index 00d01ed..0000000 --- a/template.templ +++ /dev/null @@ -1,270 +0,0 @@ -package main - -import ( - "context" - - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// PageData captures the inputs needed to render an Art Deco page template. -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 -} - -// parsePageData reads a page-render doc into the typed PageData used by templ. -func parsePageData(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 := "dark" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: bn.ParseSiteSettings(doc), - PageMeta: bn.ParsePageMeta(doc), - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: bn.ParseEngagementConfig(doc), - } -} - -// htmlClassForMode returns the html-element class hint that flips dark mode. -func htmlClassForMode(mode string) string { - if mode == "dark" { - return "dark" - } - return "" -} - -// ArtDecoDefault — centered symmetric layout with gold rule header and footer. -templ ArtDecoDefault(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/art-deco/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["header"]) -
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
-

No content blocks assigned to this page.

-
- } -
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// ArtDecoLanding — Marquee Landing: wide hero, reservation strip, CTA. -templ ArtDecoLanding(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/art-deco/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["marquee"]) -
-
- if main, ok := data.Slots["main"]; ok && main != "" { -
- @templ.Raw(main) -
- } -
-
- @templ.Raw(data.Slots["cta"]) -
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// ArtDecoArticle — narrow editorial column for press, menus and stories. -templ ArtDecoArticle(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/art-deco/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["header"]) -
-
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { -
- @templ.Raw(main) -
- } else { -
-

No content blocks assigned to this page.

-
- } -
- -
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// ArtDecoFullWidth — Grand Ballroom: edge-to-edge gallery layout. -templ ArtDecoFullWidth(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/art-deco/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["header"]) -
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
-

No content blocks assigned to this page.

-
- } -
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// Page-render funcs adapt typed PageData into templ.Component values. - -func RenderArtDecoDefault(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoDefault(parsePageData(doc)) -} - -func RenderArtDecoLanding(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoLanding(parsePageData(doc)) -} - -func RenderArtDecoArticle(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoArticle(parsePageData(doc)) -} - -func RenderArtDecoFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoFullWidth(parsePageData(doc)) -} diff --git a/template_templ.go b/template_templ.go deleted file mode 100644 index 46bb3e0..0000000 --- a/template_templ.go +++ /dev/null @@ -1,607 +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 captures the inputs needed to render an Art Deco page template. -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 -} - -// parsePageData reads a page-render doc into the typed PageData used by templ. -func parsePageData(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 := "dark" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: bn.ParseSiteSettings(doc), - PageMeta: bn.ParsePageMeta(doc), - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: bn.ParseEngagementConfig(doc), - } -} - -// htmlClassForMode returns the html-element class hint that flips dark mode. -func htmlClassForMode(mode string) string { - if mode == "dark" { - return "dark" - } - return "" -} - -// ArtDecoDefault — centered symmetric layout with gold rule header and footer. -func ArtDecoDefault(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 = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 = []any{htmlClassForMode(data.ThemeMode)} - 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, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - 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/art-deco/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 - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") - 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, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).Render(ctx, templ_7745c5c3_Buffer) - 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 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, 7, "

No content blocks assigned to this page.

") - 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 = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - 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 - } - 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, 10, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// ArtDecoLanding — Marquee Landing: wide hero, reservation strip, CTA. -func ArtDecoLanding(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, 11, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 = []any{htmlClassForMode(data.ThemeMode)} - 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, 12, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - 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/art-deco/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 - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") - 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, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["marquee"]).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 - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
") - 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, 18, "
") - 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 = templ.Raw(data.Slots["cta"]).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["footer"]).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 = 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, 22, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// ArtDecoArticle — narrow editorial column for press, menus and stories. -func ArtDecoArticle(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_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var8 = []any{htmlClassForMode(data.ThemeMode)} - 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, 24, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - 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/art-deco/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 - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") - 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, 27, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).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 - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
") - 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, 30, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "

No content blocks assigned to this page.

") - 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 - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - 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 = 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, 35, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// ArtDecoFullWidth — Grand Ballroom: edge-to-edge gallery layout. -func ArtDecoFullWidth(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_Var10 := templ.GetChildren(ctx) - if templ_7745c5c3_Var10 == nil { - templ_7745c5c3_Var10 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 = []any{htmlClassForMode(data.ThemeMode)} - 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, 37, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - 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/art-deco/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 - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "") - 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, 40, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") - 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, 42, "

No content blocks assigned to this page.

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
") - 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, 45, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// Page-render funcs adapt typed PageData into templ.Component values. - -func RenderArtDecoDefault(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoDefault(parsePageData(doc)) -} - -func RenderArtDecoLanding(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoLanding(parsePageData(doc)) -} - -func RenderArtDecoArticle(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoArticle(parsePageData(doc)) -} - -func RenderArtDecoFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return ArtDecoFullWidth(parsePageData(doc)) -} - -var _ = templruntime.GeneratedTemplate diff --git a/templates/art-deco/article.ninjatpl b/templates/art-deco/article.ninjatpl new file mode 100644 index 0000000..2a3f335 --- /dev/null +++ b/templates/art-deco/article.ninjatpl @@ -0,0 +1,20 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.header|safe }}
+
+
+
+ {% if slots.main %}
{{ slots.main|safe }}
{% else %}

No content blocks assigned to this page.

{% endif %} +
+ +
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/art-deco/default.ninjatpl b/templates/art-deco/default.ninjatpl new file mode 100644 index 0000000..15ba46e --- /dev/null +++ b/templates/art-deco/default.ninjatpl @@ -0,0 +1,17 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.header|safe }}
+
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}

No content blocks assigned to this page.

{% endif %} +
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/art-deco/full-width.ninjatpl b/templates/art-deco/full-width.ninjatpl new file mode 100644 index 0000000..8e6c825 --- /dev/null +++ b/templates/art-deco/full-width.ninjatpl @@ -0,0 +1,15 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.header|safe }}
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}

No content blocks assigned to this page.

{% endif %} +
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/art-deco/landing.ninjatpl b/templates/art-deco/landing.ninjatpl new file mode 100644 index 0000000..56b97f2 --- /dev/null +++ b/templates/art-deco/landing.ninjatpl @@ -0,0 +1,16 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.marquee|safe }}
+
+ {% if slots.main %}
{{ slots.main|safe }}
{% endif %} +
+
{{ slots.cta|safe }}
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/email/art-deco.ninjatpl b/templates/email/art-deco.ninjatpl new file mode 100644 index 0000000..8ad3c74 --- /dev/null +++ b/templates/email/art-deco.ninjatpl @@ -0,0 +1,64 @@ + + + + + + + + + {{ site.name }} + + + + {% if preview_text %}
{{ preview_text }}
{% endif %} + + + + +
+ + + + + + + + + + + + + + +
+ + diff --git a/templates/overrides/art-deco/button.ninjatpl b/templates/overrides/art-deco/button.ninjatpl new file mode 100644 index 0000000..253b950 --- /dev/null +++ b/templates/overrides/art-deco/button.ninjatpl @@ -0,0 +1 @@ +{% if label %}{% if url %}{{ label }}{% else %}{% endif %}{% endif %} diff --git a/templates/overrides/art-deco/heading.ninjatpl b/templates/overrides/art-deco/heading.ninjatpl new file mode 100644 index 0000000..4573ef2 --- /dev/null +++ b/templates/overrides/art-deco/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/art-deco/image.ninjatpl b/templates/overrides/art-deco/image.ninjatpl new file mode 100644 index 0000000..4230174 --- /dev/null +++ b/templates/overrides/art-deco/image.ninjatpl @@ -0,0 +1 @@ +
{{ alt }}
{% if caption %}
{{ caption }}
{% endif %}
diff --git a/templates/overrides/art-deco/text.ninjatpl b/templates/overrides/art-deco/text.ninjatpl new file mode 100644 index 0000000..73aa570 --- /dev/null +++ b/templates/overrides/art-deco/text.ninjatpl @@ -0,0 +1 @@ +
{{ text|safe }}
diff --git a/text_override.go b/text_override.go deleted file mode 100644 index 244252f..0000000 --- a/text_override.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// ArtDecoTextBlock overrides the built-in "text" block when the Art Deco theme is active. -// Renders prose in Cormorant body with a classical italic drop-cap on the first paragraph. -// Content: {"text": "", "class": "optional-extra-class"} -func ArtDecoTextBlock(ctx context.Context, content map[string]any) string { - data := TextOverrideData{ - Text: getString(content, "text"), - Class: getString(content, "class"), - } - - var buf bytes.Buffer - _ = artDecoTextComponent(data).Render(ctx, &buf) - return buf.String() -} - -// TextOverrideData is the typed view for the text override component. -type TextOverrideData struct { - Text string - Class string -} diff --git a/text_override.templ b/text_override.templ deleted file mode 100644 index e53f46a..0000000 --- a/text_override.templ +++ /dev/null @@ -1,13 +0,0 @@ -package main - -// artDecoTextComponent renders rich text body copy with a classical italic dropcap. -templ artDecoTextComponent(data TextOverrideData) { -
- @templ.Raw(data.Text) -
-} diff --git a/text_override_templ.go b/text_override_templ.go deleted file mode 100644 index 64fd744..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" - -// artDecoTextComponent renders rich text body copy with a classical italic dropcap. -func artDecoTextComponent(data TextOverrideData) 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{"deco-dropcap prose max-w-none", data.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(data.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