Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/art-deco. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
175 lines
5.4 KiB
Go
175 lines
5.4 KiB
Go
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,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|