Alex Dunmow 4713787bbd initial: theme plugin corporate-modernist
Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously
an unversioned directory inside ~/src/blockninja-themes/corporate-modernist.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 14:11:24 +08:00

170 lines
5.6 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 func to templates.TemplateFunc.
func wrap(f func(ctx context.Context, doc map[string]any) templ.Component) templates.TemplateFunc {
return func(ctx context.Context, doc map[string]any) templates.HTMLComponent {
return f(ctx, doc)
}
}
// Register wires Corporate Modernist's system template, page templates,
// theme-owned blocks, built-in overrides, and email wrapper.
//
// Schema loading must precede block registration so that the registry can
// bind schemas to block keys at runtime.
func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error {
// 1. System template.
tr.RegisterSystemTemplate(templates.SystemTemplateMeta{
Key: "corporate-modernist",
Title: "Corporate Modernist",
Description: "Swiss-grid B2B theme with restrained typography, a single configurable accent, and trust-signal blocks for enterprise sites.",
})
// 2. Page templates.
if err := tr.RegisterPageTemplate("corporate-modernist", templates.PageTemplateMeta{
Key: "default",
Title: "Default",
Description: "Header + 12-col main + footer, capped at 1280px.",
Slots: []string{"header", "main", "footer"},
}, wrap(RenderCM)); err != nil {
return err
}
if err := tr.RegisterPageTemplate("corporate-modernist", templates.PageTemplateMeta{
Key: "landing",
Title: "Landing",
Description: "Hero band + main + closing CTA + footer.",
Slots: []string{"hero", "main", "cta", "footer"},
}, wrap(RenderCMLanding)); err != nil {
return err
}
if err := tr.RegisterPageTemplate("corporate-modernist", templates.PageTemplateMeta{
Key: "article",
Title: "Article",
Description: "Centered measure for long-form thought leadership.",
Slots: []string{"header", "main", "aside", "footer"},
}, wrap(RenderCMArticle)); err != nil {
return err
}
if err := tr.RegisterPageTemplate("corporate-modernist", templates.PageTemplateMeta{
Key: "full-width",
Title: "Full width",
Description: "Edge-to-edge sections, internal grid kept.",
Slots: []string{"header", "main", "footer"},
}, wrap(RenderCMFullWidth)); err != nil {
return err
}
// 3. Schemas — MUST precede block registrations.
if err := br.LoadSchemasFromFS(Schemas()); err != nil {
return err
}
// 4. Theme-owned blocks.
br.Register(HeroStatementMeta, HeroStatementBlock)
br.Register(LogoStripMeta, LogoStripBlock)
br.Register(TestimonialQuoteMeta, TestimonialQuoteBlock)
br.Register(CaseStudyCardMeta, CaseStudyCardBlock)
br.Register(LeadershipGridMeta, LeadershipGridBlock)
br.Register(StatPairMeta, StatPairBlock)
br.Register(CTAStripMeta, CTAStripBlock)
br.Register(FooterMeta, FooterBlock)
// 5. Built-in overrides — heading, text, button, card.
br.RegisterTemplateOverride("corporate-modernist", "heading", CorporateModernistHeadingBlock)
br.RegisterTemplateOverride("corporate-modernist", "text", CorporateModernistTextBlock)
br.RegisterTemplateOverride("corporate-modernist", "button", CorporateModernistButtonBlock)
br.RegisterTemplateOverride("corporate-modernist", "card", CorporateModernistCardBlock)
// 6. Email wrapper.
tr.RegisterEmailWrapper("corporate-modernist", CorporateModernistEmailWrapper)
return nil
}
// DefaultMasterPages returns Corporate Modernist's two seeded master pages.
// Slot names match the page templates registered above.
func DefaultMasterPages() []plugin.MasterPageDefinition {
return []plugin.MasterPageDefinition{
{
Key: "corporate-modernist:default-master",
Title: "Corporate Modernist Default Master",
PageTemplates: []string{"default", "article"},
Blocks: []plugin.MasterPageBlock{
{
BlockKey: "navbar",
Title: "Main Navigation",
Content: map[string]any{"menuName": "main", "style": "underline"},
Slot: "header",
SortOrder: 0,
},
{
BlockKey: "slot",
Title: "Main Content Slot",
Content: map[string]any{"slotName": "main"},
Slot: "main",
SortOrder: 0,
},
{
BlockKey: "corporate-modernist:footer",
Title: "Site Footer",
Content: map[string]any{"variant": "compact", "showLegal": true},
Slot: "footer",
SortOrder: 0,
},
},
},
{
Key: "corporate-modernist:landing-master",
Title: "Corporate Modernist Landing Master",
PageTemplates: []string{"landing", "full-width"},
Blocks: []plugin.MasterPageBlock{
{
BlockKey: "navbar",
Title: "Main Navigation",
Content: map[string]any{"menuName": "main", "style": "underline"},
Slot: "header",
SortOrder: 0,
},
{
BlockKey: "corporate-modernist:hero_statement",
Title: "Landing Hero",
Content: map[string]any{"eyebrow": "Enterprise", "headline": "Trusted by 200+ boards"},
Slot: "hero",
SortOrder: 0,
},
{
BlockKey: "slot",
Title: "Main Content Slot",
Content: map[string]any{"slotName": "main"},
Slot: "main",
SortOrder: 0,
},
{
BlockKey: "corporate-modernist:cta_strip",
Title: "Closing CTA",
Content: map[string]any{"variant": "book-call"},
Slot: "cta",
SortOrder: 0,
},
{
BlockKey: "corporate-modernist:footer",
Title: "Site Footer",
Content: map[string]any{"variant": "full", "showLegal": true},
Slot: "footer",
SortOrder: 0,
},
},
},
}
}