render

package
v0.0.0-...-9457e37 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package render handles dynamic-section substitution in served HTML.

Per gocodealone-multisite SPEC.md V14: dynamic sections in static HTML are rendered server-side via marker substitution; ⊥ client-side JS fetch unless explicit.

Markers look like:

<!-- multisite:latest-blog -->

At render time the renderer finds each marker and replaces it with the HTML produced by the configured template for that section id. The marker shape is intentionally invisible to browsers — if a tenant strips the host's templates, the page degrades to a literal HTML comment (no broken-page artifact).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FindMarkerIDs

func FindMarkerIDs(html []byte) []string

FindMarkerIDs returns the unique marker ids referenced in the given HTML, in order of first occurrence. Useful for validation passes (warn when manifest declares ids that don't appear in the bundle).

func Substitute

func Substitute(ctx context.Context, html []byte, registry *Registry, specs []SectionSpec, opts SubstituteOptions) ([]byte, error)

Substitute walks `html` and replaces every multisite marker with the rendered output of its declared template.

  • registry: template registry the host wires at boot.
  • specs: the tenant's multisite.yaml dynamic_sections[] list.

Returns the rewritten HTML. On a template Render error, returns the partial-progress result + the error (caller decides whether to serve-or-fail).

Types

type MissingSpecPolicy

type MissingSpecPolicy int

MissingSpecPolicy controls behaviour for un-declared marker ids.

const (
	// MissingSpecSilent leaves the original comment intact.
	MissingSpecSilent MissingSpecPolicy = iota
	// MissingSpecError aborts substitution and returns an error.
	MissingSpecError
)

type MissingTemplatePolicy

type MissingTemplatePolicy int

MissingTemplatePolicy controls behaviour for declared-but-unregistered template.

const (
	// MissingTemplateSilent leaves the original comment intact.
	MissingTemplateSilent MissingTemplatePolicy = iota
	// MissingTemplateError aborts substitution and returns an error.
	MissingTemplateError
)

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry maps template name → SectionTemplate.

func NewRegistry

func NewRegistry() *Registry

func (*Registry) Get

func (r *Registry) Get(name string) (SectionTemplate, bool)

func (*Registry) Register

func (r *Registry) Register(t SectionTemplate) error

type SectionSpec

type SectionSpec struct {
	ID       string            // matches the marker id
	Template string            // template name (must resolve in Registry)
	Params   map[string]string // per-section params passed through to template.Render
}

SectionSpec describes what template to invoke for a marker id, taken from the tenant's multisite.yaml `dynamic_sections[]` entries.

type SectionTemplate

type SectionTemplate interface {
	Name() string
	Render(ctx context.Context, sectionID string, params map[string]string) (string, error)
}

SectionTemplate is the contract a CMS template (e.g. blog-list, contact-form) implements. The renderer passes the section id + a tenant-scoped context; the template returns the HTML to substitute.

func StringTemplate

func StringTemplate(name, body string) SectionTemplate

StringTemplate returns a SectionTemplate that always renders `body`. For tests + quick wiring.

type SubstituteOptions

type SubstituteOptions struct {
	// OnMissingTemplate decides what to do when a marker references an
	// id that the tenant's manifest declares BUT the host has no
	// registered template for. Default: leave the comment in place
	// (silent degrade).
	OnMissingTemplate MissingTemplatePolicy

	// OnMissingSpec decides what to do when a marker references an id
	// that the tenant's manifest does NOT declare. Default: leave the
	// comment in place (the marker is a no-op).
	OnMissingSpec MissingSpecPolicy
}

SubstituteOptions controls how Substitute behaves on edge cases.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL