Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/magazine-bold. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
173 lines
5.4 KiB
Go
173 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 to templates.TemplateFunc.
|
|
func wrap(f func(ctx context.Context, doc map[string]any) templ.Component) templates.TemplateFunc {
|
|
return func(ctx context.Context, doc map[string]any) templates.HTMLComponent {
|
|
return f(ctx, doc)
|
|
}
|
|
}
|
|
|
|
// Register is the plugin entry point that registers the Magazine Bold system
|
|
// template, page templates, blocks, overrides and email wrapper.
|
|
func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error {
|
|
tr.RegisterSystemTemplate(templates.SystemTemplateMeta{
|
|
Key: "magazine-bold",
|
|
Title: "Magazine Bold",
|
|
Description: "Editorial-print theme with oversized display type, asymmetric grids and rotating color-block accents for fashion, streetwear and culture publications.",
|
|
})
|
|
|
|
// Page templates — slots per spec §6 / UAT §3.
|
|
if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{
|
|
Key: "default",
|
|
Title: "Default",
|
|
Description: "Standard editorial page with masthead, asymmetric main, footer colophon.",
|
|
Slots: []string{"masthead", "main", "colophon"},
|
|
}, wrap(RenderMagazineBold)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{
|
|
Key: "landing",
|
|
Title: "Issue Landing",
|
|
Description: "Cover-story hero plus issue navigation strip.",
|
|
Slots: []string{"cover", "secondary", "main", "colophon"},
|
|
}, wrap(RenderMagazineBoldLanding)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{
|
|
Key: "article",
|
|
Title: "Article / Feature",
|
|
Description: "Long-form feature with deck, byline rail and pull-quote gutter.",
|
|
Slots: []string{"masthead", "deck", "main", "colophon"},
|
|
}, wrap(RenderMagazineBoldArticle)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tr.RegisterPageTemplate("magazine-bold", templates.PageTemplateMeta{
|
|
Key: "full-width",
|
|
Title: "Full Bleed",
|
|
Description: "Edge-to-edge photo-essay layout.",
|
|
Slots: []string{"masthead", "main", "colophon"},
|
|
}, wrap(RenderMagazineBoldFullWidth)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Schemas BEFORE blocks (per UAT §3).
|
|
if err := br.LoadSchemasFromFS(Schemas()); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Theme blocks.
|
|
br.Register(MastheadBlockMeta, MastheadBlock)
|
|
br.Register(CoverStoryBlockMeta, CoverStoryBlock)
|
|
br.Register(PhotoEssayBlockMeta, PhotoEssayBlock)
|
|
br.Register(PullQuoteBlockMeta, PullQuoteBlock)
|
|
br.Register(IssueArchiveBlockMeta, IssueArchiveBlock)
|
|
br.Register(ColophonBlockMeta, ColophonBlock)
|
|
|
|
// Built-in overrides — only active when this theme is selected.
|
|
br.RegisterTemplateOverride("magazine-bold", "heading", HeadingOverrideBlock)
|
|
br.RegisterTemplateOverride("magazine-bold", "text", TextOverrideBlock)
|
|
br.RegisterTemplateOverride("magazine-bold", "image", ImageOverrideBlock)
|
|
br.RegisterTemplateOverride("magazine-bold", "button", ButtonOverrideBlock)
|
|
|
|
// Branded email wrapper.
|
|
tr.RegisterEmailWrapper("magazine-bold", MagazineBoldEmailWrapper)
|
|
|
|
return nil
|
|
}
|
|
|
|
// DefaultMasterPages returns the default master pages Magazine Bold seeds.
|
|
func DefaultMasterPages() []plugin.MasterPageDefinition {
|
|
return []plugin.MasterPageDefinition{
|
|
{
|
|
Key: "magazine-bold:default-master",
|
|
Title: "Magazine Bold — Default",
|
|
PageTemplates: []string{"default", "article"},
|
|
Blocks: []plugin.MasterPageBlock{
|
|
{
|
|
BlockKey: "navbar",
|
|
Title: "Masthead Nav",
|
|
Content: map[string]any{"menuName": "main"},
|
|
Slot: "masthead",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "magazine-bold:masthead",
|
|
Title: "Issue Masthead",
|
|
Content: map[string]any{"issueNo": "01", "tagline": "Vol. 1 / Spring"},
|
|
Slot: "masthead",
|
|
SortOrder: 1,
|
|
},
|
|
{
|
|
BlockKey: "slot",
|
|
Title: "Main Slot",
|
|
Content: map[string]any{"slotName": "main"},
|
|
Slot: "main",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "magazine-bold:colophon",
|
|
Title: "Colophon",
|
|
Content: map[string]any{"showSocial": "true"},
|
|
Slot: "colophon",
|
|
SortOrder: 0,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Key: "magazine-bold:landing-master",
|
|
Title: "Magazine Bold — Issue Landing",
|
|
PageTemplates: []string{"landing", "full-width"},
|
|
Blocks: []plugin.MasterPageBlock{
|
|
{
|
|
BlockKey: "navbar",
|
|
Title: "Masthead Nav",
|
|
Content: map[string]any{"menuName": "main"},
|
|
Slot: "masthead",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "magazine-bold:cover_story",
|
|
Title: "Cover Story",
|
|
Content: map[string]any{"issueNo": "01"},
|
|
Slot: "cover",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "magazine-bold:issue_archive",
|
|
Title: "Issue Archive",
|
|
Content: map[string]any{"bucketSlug": "issues"},
|
|
Slot: "secondary",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "slot",
|
|
Title: "Main Slot",
|
|
Content: map[string]any{"slotName": "main"},
|
|
Slot: "main",
|
|
SortOrder: 0,
|
|
},
|
|
{
|
|
BlockKey: "magazine-bold:colophon",
|
|
Title: "Colophon",
|
|
Content: map[string]any{"showSocial": "true"},
|
|
Slot: "colophon",
|
|
SortOrder: 0,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|