Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/earthen. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
181 lines
5.2 KiB
Go
181 lines
5.2 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 to templates.TemplateFunc.
|
|
// templ.Component already implements templates.HTMLComponent via Render.
|
|
func wrap(f func(ctx context.Context, doc map[string]any) templ.Component) templates.TemplateFunc {
|
|
return func(ctx context.Context, doc map[string]any) templates.HTMLComponent {
|
|
return f(ctx, doc)
|
|
}
|
|
}
|
|
|
|
// Register is the plugin entry point that registers the Earthen system template,
|
|
// four page templates, six theme blocks, five overrides, and the email wrapper.
|
|
func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error {
|
|
tr.RegisterSystemTemplate(templates.SystemTemplateMeta{
|
|
Key: "earthen",
|
|
Title: "Earthen",
|
|
Description: "Botanical nonprofit theme in moss, clay, sage and cream",
|
|
})
|
|
|
|
if err := tr.RegisterPageTemplate("earthen", templates.PageTemplateMeta{
|
|
Key: "default",
|
|
Title: "Default",
|
|
Description: "Standard nonprofit page with header, main and footer",
|
|
Slots: []string{"header", "main", "footer"},
|
|
}, wrap(RenderEarthenDefault)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tr.RegisterPageTemplate("earthen", templates.PageTemplateMeta{
|
|
Key: "landing",
|
|
Title: "Landing",
|
|
Description: "Mission hero plus CTA bands for campaigns and donation drives",
|
|
Slots: []string{"hero", "main", "cta", "footer"},
|
|
}, wrap(RenderEarthenLanding)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tr.RegisterPageTemplate("earthen", templates.PageTemplateMeta{
|
|
Key: "article",
|
|
Title: "Article",
|
|
Description: "Long-form storytelling with byline rail",
|
|
Slots: []string{"header", "lede", "main", "aside", "footer"},
|
|
}, wrap(RenderEarthenArticle)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tr.RegisterPageTemplate("earthen", templates.PageTemplateMeta{
|
|
Key: "full-width",
|
|
Title: "Full Width",
|
|
Description: "Edge-to-edge imagery for reports and galleries",
|
|
Slots: []string{"header", "main", "footer"},
|
|
}, wrap(RenderEarthenFullWidth)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := br.LoadSchemasFromFS(Schemas()); err != nil {
|
|
return err
|
|
}
|
|
|
|
br.Register(DonationCTABlockMeta, DonationCTABlock)
|
|
br.Register(ImpactMetricsBlockMeta, ImpactMetricsBlock)
|
|
br.Register(PartnerLogosBlockMeta, PartnerLogosBlock)
|
|
br.Register(FieldNoteBlockMeta, FieldNoteBlock)
|
|
br.Register(BotanicalDividerBlockMeta, BotanicalDividerBlock)
|
|
br.Register(FooterBlockMeta, FooterBlock)
|
|
|
|
br.RegisterTemplateOverride("earthen", "heading", EarthenHeadingBlock)
|
|
br.RegisterTemplateOverride("earthen", "text", EarthenTextBlock)
|
|
br.RegisterTemplateOverride("earthen", "button", EarthenButtonBlock)
|
|
br.RegisterTemplateOverride("earthen", "image", EarthenImageBlock)
|
|
br.RegisterTemplateOverride("earthen", "card", EarthenCardBlock)
|
|
|
|
tr.RegisterEmailWrapper("earthen", EarthenEmailWrapper)
|
|
|
|
return nil
|
|
}
|
|
|
|
// DefaultMasterPages returns the default master pages that Earthen provisions
|
|
// on first plugin load.
|
|
func DefaultMasterPages() []plugin.MasterPageDefinition {
|
|
return []plugin.MasterPageDefinition{
|
|
{
|
|
Key: "earthen:default-master",
|
|
Title: "Earthen Default Master",
|
|
PageTemplates: []string{"default", "article"},
|
|
Blocks: []plugin.MasterPageBlock{
|
|
{
|
|
BlockKey: "navbar",
|
|
Title: "Main Navigation",
|
|
Content: map[string]any{"menuName": "main"},
|
|
Slot: "header",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "slot",
|
|
Title: "Main Content",
|
|
Content: map[string]any{"slotName": "main"},
|
|
Slot: "main",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "earthen:donation_cta",
|
|
Title: "Donation Rail",
|
|
Content: map[string]any{
|
|
"amounts": []any{25.0, 50.0, 100.0},
|
|
"headline": "Plant the next acre.",
|
|
},
|
|
Slot: "main",
|
|
SortOrder: 100,
|
|
},
|
|
{
|
|
BlockKey: "earthen:footer",
|
|
Title: "Site Footer",
|
|
Content: map[string]any{
|
|
"showNewsletter": true,
|
|
"tagline": "Rooted in place.",
|
|
},
|
|
Slot: "footer",
|
|
SortOrder: 0,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Key: "earthen:landing-master",
|
|
Title: "Earthen Landing Master",
|
|
PageTemplates: []string{"landing", "full-width"},
|
|
Blocks: []plugin.MasterPageBlock{
|
|
{
|
|
BlockKey: "navbar",
|
|
Title: "Main Navigation",
|
|
Content: map[string]any{"menuName": "main"},
|
|
Slot: "hero",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "slot",
|
|
Title: "Hero Slot",
|
|
Content: map[string]any{"slotName": "hero"},
|
|
Slot: "hero",
|
|
SortOrder: 10,
|
|
},
|
|
{
|
|
BlockKey: "slot",
|
|
Title: "Main Slot",
|
|
Content: map[string]any{"slotName": "main"},
|
|
Slot: "main",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "earthen:donation_cta",
|
|
Title: "Donation CTA",
|
|
Content: map[string]any{
|
|
"amounts": []any{25.0, 50.0, 100.0, 250.0},
|
|
},
|
|
Slot: "cta",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "earthen:footer",
|
|
Title: "Footer",
|
|
Content: map[string]any{
|
|
"showNewsletter": true,
|
|
},
|
|
Slot: "footer",
|
|
SortOrder: 0,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|