theme

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 9, 2026 License: MIT Imports: 9 Imported by: 8

README

go-theme

Theming utilities for Go projects. Provides a manifest schema, loaders, a registry to support themes.

Install

go get github.com/goliatone/go-theme

Core Concepts

  • Manifest: theme metadata, tokens, assets, templates, variants. JSON or YAML.
  • Loader: read manifests from bytes/file/dir with fs.FS or embed.FS.
  • Registry: store and fetch themes by name/version with fallback.
  • Resolvers: Selector/Selection expose templates, assets, tokens, CSS vars, renderer configs, and resolved snapshots for hosts.

Quick Start

import (
    "embed"
    theme "github.com/goliatone/go-theme"
)

//go:embed themes/acme/*
var themeFS embed.FS

// load manifest
m, _ := theme.LoadDir(themeFS, "themes/acme")

// register
reg := theme.NewRegistry()
_ = reg.Register(m)

// shared selector and selection
selector := theme.Selector{Registry: reg, DefaultTheme: "acme-admin", DefaultVariant: "light"}
sel, _ := selector.Select("", "")

// template usage
cssVars := sel.CSSVariables("")                         // map of "--token": value
logoURL, _ := sel.Asset("logo")                         // prefix/CDN aware
headerTpl := sel.Template("layout.header", "default/header.tmpl")

// full resolved snapshot usage (for host adapters)
snapshot := sel.Snapshot()
_ = snapshot // theme/variant + merged tokens/assets/templates + resolved asset prefix

// renderer usage
rendererCfg := sel.RendererTheme(map[string]string{
    "forms.input":  "default/forms/input.tmpl",
    "forms.select": "default/forms/select.tmpl",
})
_ = rendererCfg // pass tokens, CSS vars, partials, and AssetURL to renderers

Partial Naming Conventions

  • layout.header, layout.footer, layout.nav
  • forms.input, forms.select, forms.checkbox, forms.radio, forms.textarea, forms.button, forms.field-wrapper
  • components.alert, components.card, components.table
  • Keep partials in templates/<area>/<name>.tmpl (or similar) and reference the keys above in the manifest.
  • Variant overrides live under variants.<name>.templates.<key>.
  • Selector resolution order: variant → base → your fallback path.

Asset Handling

  • assets.prefix is prepended to asset file paths; variant assets.prefix overrides the base prefix.
  • Asset file paths may be relative or start with /; leading slashes are trimmed before joining.
  • CDN prefixes (contain ://) are concatenated with a single /.
  • Missing asset keys return an empty string/false from Selection.Asset.

Resolved Snapshot

  • Use Selection.Snapshot() when integrations need one complete payload instead of per-key lookups.
  • Snapshot precedence is deterministic:
    • Tokens: variant overrides base.
    • Templates: variant override key, else base key.
    • Assets: variant file override key, else base key, preserving Selection.Asset prefix behavior.
  • AssetPrefix resolves to variants.<name>.assets.prefix when set, otherwise base assets.prefix.

Examples

  • Manifests: docs/examples/basic-theme.yaml, docs/examples/basic-theme.json
  • Example wiring (templates + renderers): docs/examples/example-app.md

Documentation

Overview

Package theme provides shared theming manifest definitions, loaders, and a simple in-memory registry.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrThemeNotFound is returned when a theme name has no registered manifests.
	ErrThemeNotFound = errors.New("theme not found")
	// ErrVersionNotFound is returned when a specific version cannot be located.
	ErrVersionNotFound = errors.New("theme version not found")
)

Functions

This section is empty.

Types

type AssetResolver

type AssetResolver interface {
	Asset(key string) (string, bool)
}

AssetResolver resolves asset URLs/paths.

type Assets

type Assets struct {
	Prefix string            `json:"prefix,omitempty" yaml:"prefix,omitempty"`
	Files  map[string]string `json:"files,omitempty" yaml:"files,omitempty"`
}

Assets groups static assets and optional prefix/CDN root.

type Manifest

type Manifest struct {
	Name        string             `json:"name" yaml:"name"`
	Version     string             `json:"version" yaml:"version"`
	Description string             `json:"description,omitempty" yaml:"description,omitempty"`
	Tokens      map[string]string  `json:"tokens,omitempty" yaml:"tokens,omitempty"`
	Fonts       map[string]string  `json:"fonts,omitempty" yaml:"fonts,omitempty"`
	Assets      Assets             `json:"assets,omitempty" yaml:"assets,omitempty"`
	Templates   map[string]string  `json:"templates,omitempty" yaml:"templates,omitempty"`
	Variants    map[string]Variant `json:"variants,omitempty" yaml:"variants,omitempty"`
}

Manifest defines the shape of a theme file that downstream systems (go-cms, go-formgen) can consume.

func LoadBytes

func LoadBytes(data []byte, format string) (*Manifest, error)

LoadBytes parses a manifest from raw bytes. If format is empty, it will try JSON then YAML.

func LoadDir

func LoadDir(fsys fs.FS, dir string) (*Manifest, error)

LoadDir searches common manifest filenames within a directory in the provided fs.FS.

func LoadFile

func LoadFile(fsys fs.FS, manifestPath string) (*Manifest, error)

LoadFile reads a manifest from a given fs.FS path, inferring format from the extension.

func (Manifest) CSSVariables

func (m Manifest) CSSVariables(prefix, variant string) map[string]string

CSSVariables returns a CSS variable map (prefixed with "--" unless overridden) for a variant.

func (Manifest) TokensForVariant

func (m Manifest) TokensForVariant(variant string) map[string]string

TokensForVariant merges base tokens with the requested variant (variant tokens take precedence).

func (*Manifest) Validate

func (m *Manifest) Validate() error

Validate checks required fields and basic integrity for maps/variants.

type ManifestRef

type ManifestRef struct {
	Name        string
	Version     string
	Description string
}

ManifestRef summarizes a stored manifest.

type MemoryRegistry

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

MemoryRegistry is a minimal in-memory implementation of Registry and ThemeProvider.

func NewRegistry

func NewRegistry() *MemoryRegistry

NewRegistry constructs an empty MemoryRegistry.

func (*MemoryRegistry) Get

func (r *MemoryRegistry) Get(name string, opts ...QueryOption) (*Manifest, error)

Get fetches a manifest by name, optionally constrained to a version with fallback to the latest.

func (*MemoryRegistry) List

func (r *MemoryRegistry) List() []ManifestRef

List returns a sorted list of all stored manifests.

func (*MemoryRegistry) Register

func (r *MemoryRegistry) Register(manifest *Manifest) error

Register validates and stores a manifest. Existing entries for the same name+version are overwritten.

func (*MemoryRegistry) Theme

func (r *MemoryRegistry) Theme(name string, opts ...QueryOption) (*Manifest, error)

Theme is an alias for Get to satisfy ThemeProvider.

func (*MemoryRegistry) Themes

func (r *MemoryRegistry) Themes() []ManifestRef

Themes is an alias for List to satisfy ThemeProvider.

type QueryOption

type QueryOption func(*queryOptions)

QueryOption modifies how registry lookups behave.

func WithVersion

func WithVersion(version string) QueryOption

WithVersion requests a specific manifest version.

func WithoutFallback

func WithoutFallback() QueryOption

WithoutFallback disables fallback to the latest version when a specific one is missing.

type Registry

type Registry interface {
	Register(manifest *Manifest) error
	Get(name string, opts ...QueryOption) (*Manifest, error)
	List() []ManifestRef
}

Registry defines methods to register and retrieve theme manifests.

type RendererConfig

type RendererConfig struct {
	Theme    string
	Variant  string
	Partials map[string]string
	Tokens   map[string]string
	CSSVars  map[string]string
	AssetURL func(string) string
}

RendererConfig bundles resolved partials, tokens, CSS vars, and an asset resolver for renderers.

type ResolvedSelection added in v0.3.0

type ResolvedSelection struct {
	Theme       string
	Variant     string
	Tokens      map[string]string
	Assets      map[string]string
	Templates   map[string]string
	AssetPrefix string
}

ResolvedSelection is a complete theme snapshot with merged variant/base values.

type Selection

type Selection struct {
	Theme    string
	Variant  string
	Manifest *Manifest
}

Selection holds the chosen theme/variant and provides resolvers for templates, assets, and tokens.

func (Selection) Asset

func (s Selection) Asset(key string) (string, bool)

Asset returns a themed asset path with prefix handling (variant overrides then base). Bool indicates presence.

func (Selection) CSSVariables

func (s Selection) CSSVariables(prefix string) map[string]string

CSSVariables returns CSS vars for the variant with the provided prefix (defaults to "--" if empty).

func (Selection) Partials

func (s Selection) Partials(fallbacks map[string]string) map[string]string

Partials resolves a map of template keys to fallback paths.

func (Selection) RendererTheme

func (s Selection) RendererTheme(fallbacks map[string]string) RendererConfig

RendererTheme builds a RendererConfig given a set of fallback partials.

func (Selection) Snapshot added in v0.3.0

func (s Selection) Snapshot() ResolvedSelection

Snapshot returns a fully resolved selection payload for integrations that need merged assets/templates/tokens.

func (Selection) Template

func (s Selection) Template(key, fallback string) string

Template resolves a template key using variant overrides, then base, then fallback.

func (Selection) Tokens

func (s Selection) Tokens() map[string]string

Tokens returns the merged token map for the selected variant.

type Selector

type Selector struct {
	Registry       ThemeProvider
	DefaultTheme   string
	DefaultVariant string
}

Selector is the default implementation of ThemeSelector using a ThemeProvider registry.

func (Selector) Select

func (s Selector) Select(themeName, variant string, opts ...QueryOption) (*Selection, error)

Select resolves a theme name/variant with fallback to defaults and returns a Selection.

type TemplateResolver

type TemplateResolver interface {
	Template(key, fallback string) string
	Partials(fallbacks map[string]string) map[string]string
}

TemplateResolver resolves templates by key with optional fallbacks.

type ThemeProvider

type ThemeProvider interface {
	Theme(name string, opts ...QueryOption) (*Manifest, error)
	Themes() []ManifestRef
}

ThemeProvider exposes read-only registry access for downstream consumers.

type ThemeSelector

type ThemeSelector interface {
	Select(themeName, variant string, opts ...QueryOption) (*Selection, error)
}

ThemeSelector selects a theme/variant and exposes resolvers.

type TokenProvider

type TokenProvider interface {
	Tokens() map[string]string
	CSSVariables(prefix string) map[string]string
}

TokenProvider exposes tokens and CSS variables for a theme/variant.

type ValidationError

type ValidationError struct {
	Issues []string
}

ValidationError aggregates manifest validation issues.

func (ValidationError) Error

func (e ValidationError) Error() string

Error implements the error interface.

type Variant

type Variant struct {
	Description string            `json:"description,omitempty" yaml:"description,omitempty"`
	Tokens      map[string]string `json:"tokens,omitempty" yaml:"tokens,omitempty"`
	Templates   map[string]string `json:"templates,omitempty" yaml:"templates,omitempty"`
	Assets      Assets            `json:"assets,omitempty" yaml:"assets,omitempty"`
}

Variant captures token/template/asset overrides for a named variant (e.g., light/dark).

Jump to

Keyboard shortcuts

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