package main import ( "bytes" "context" "git.dev.alexdunmow.com/block/core/blocks" ) // ContactSheetBlockMeta defines the Noir contact sheet block. var ContactSheetBlockMeta = blocks.BlockMeta{ Key: "contact_sheet", Title: "Contact Sheet", Description: "Numbered photograph frames with sprocket motif evoking a darkroom contact sheet.", Source: "noir", Category: blocks.CategoryContent, } // ContactSheetBlock renders a contact-sheet grid. // Content shape: {"items":[{"image":"...","frame":"01","label":"..."}, ...]} func ContactSheetBlock(ctx context.Context, content map[string]any) string { items := getSlice(content, "items") var frames []ContactFrame for i, item := range items { frame := getString(item, "frame") if frame == "" { frame = padFrame(i + 1) } frames = append(frames, ContactFrame{ Image: blocks.ResolveMediaPath(getString(item, "image")), Frame: frame, Label: getString(item, "label"), }) } var buf bytes.Buffer _ = contactSheetComponent(frames).Render(ctx, &buf) return buf.String() } // ContactFrame represents a single numbered frame in the contact sheet. type ContactFrame struct { Image string Frame string Label string } // padFrame zero-pads a frame number to two digits ("01", "02", ..., "10"). func padFrame(n int) string { if n < 10 { return "0" + intToString(n) } return intToString(n) }