Documentation
¶
Overview ¶
Package theme loads themes, resolves the template hierarchy and renders the public site.
contract.go holds the frozen wave-0 contract (types and interfaces only). The implementation arrives in wave 1.
Index ¶
- Constants
- Variables
- func BuildQuery(args map[string]any, canView bool) (content.Query, error)
- func BuilderIdentityStylesheet(identity brand.Identity) string
- func ExtraThemesDirs() []string
- func FormatDate(v any, locale, tz string, layout ...string) string
- func IdentityStylesheet(get func(key string) string) string
- func Money(amount any, currency, locale string) (string, error)
- func SettingKey(slug, key string) string
- func SupportsIdentity(info Info) bool
- func ThemesDir(cfg config.Config) string
- func ValidName(name string) bool
- type Alternate
- type BuilderPreviewOptions
- type CommentNode
- type CommentsData
- type Context
- type Info
- type InfoLookup
- type InheritedSource
- type Linker
- func (l *Linker) Archive(ctx context.Context, typ string) string
- func (l *Linker) FrontPageID(ctx context.Context) string
- func (l *Linker) Item(ctx context.Context, it *content.Item) string
- func (l *Linker) ItemWithFront(ctx context.Context, it *content.Item, frontID string) string
- func (l *Linker) MenuItem(ctx context.Context, it *menus.Item)
- func (l *Linker) SiteLocale(ctx context.Context) string
- func (l *Linker) Term(t *taxonomy.Term) string
- type Module
- type Option
- type Override
- type Pagination
- type ReparentReport
- type Service
- type SiteInfo
- type TOC
- type TOCItem
- type TemplateDTO
- type TemplateFile
- type TemplateListDTO
- type ThemeDTO
Constants ¶
const ( KindSingle = "single" KindPage = "page" KindHome = "home" KindArchive = "archive" KindTaxonomy = "taxonomy" KindSearch = "search" Kind404 = "404" Kind500 = "500" )
Built-in request kinds (spec §4.3). Modules add more with kernel.ThemeRegistry.AddKind (e.g. commerce: shop, product).
const ( // Marker500 is present in every theme-engine 500 response body. Marker500 = "<!-- gorun:500 -->" // PreviewParam enables draft overrides for users with themes.manage. PreviewParam = "gp_preview_override" // HookRenderContext filters *Context before every render. HookRenderContext = "theme.render.context" // PermManage guards the appearance screens and API. PermManage = "themes.manage" )
const ( SettingTheme = "site.theme" SettingTitle = "site.title" SettingTagline = "site.tagline" SettingLocale = "site.locale" SettingTZ = "site.timezone" SettingFront = "site.front_page" )
Setting keys read by the theme engine.
const EnvThemesDir = "GORUN_THEMES"
EnvThemesDir names the environment variable that points at the themes directory.
const EnvThemesExtra = "GORUN_THEMES_EXTRA"
EnvThemesExtra names the environment variable listing extra theme directories (separated like PATH), searched after the core directory. Brand themes live there, outside the core catalog, on the servers that use them.
const HookMenuResolveURL = "menus.resolve_url"
HookMenuResolveURL is the filter (on *menus.Item) that fills URL for menu items of kind content, term and archive.
Variables ¶
var ( // ErrNotFound is returned for unknown themes and templates. ErrNotFound = errors.New("theme: not found") // ErrInvalidName is returned for template names outside the naming scheme. ErrInvalidName = errors.New("theme: invalid template name") // ErrInvalidTheme is returned by Activate for a broken theme. ErrInvalidTheme = errors.New("theme: invalid theme") // ErrInvalidTemplate wraps a template parse error on save. ErrInvalidTemplate = errors.New("theme: invalid template") )
var ErrNoTemplate = errors.New("theme: no template matches")
ErrNoTemplate is returned when no candidate template exists in the theme.
Functions ¶
func BuildQuery ¶
BuildQuery turns a template query map into a content.Query. Keys: type, status, search, parent, locale, page, per_page (1–100, default 10), order ("published_at desc, title asc", "-published_at" or []content.Order), taxonomy (map tax → slug or slugs, or "tax:a,b"), fields (map key → value for eq, or content.Filter / {"op","value"}). Without canView the status is always "published".
func BuilderIdentityStylesheet ¶ added in v0.3.0
BuilderIdentityStylesheet returns the builder brand CSS body, or "".
func ExtraThemesDirs ¶
func ExtraThemesDirs() []string
ExtraThemesDirs returns the directories listed in $GORUN_THEMES_EXTRA.
func FormatDate ¶
FormatDate formats v (RFC3339 string or time) for locale in timezone tz. Layouts: "long" (default: "10 أكتوبر 2026" / "October 10, 2026"), "datetime" (long + 15:04), "short" (2006-01-02), "iso" (RFC3339), or a Go layout. Digits stay Latin. Unparseable strings are returned as-is.
func IdentityStylesheet ¶ added in v0.3.0
IdentityStylesheet returns the cached site-identity CSS body for settings (empty when nothing is set). Used by /site/identity.css.
func Money ¶
Money formats an amount in minor units: Money(123450, "USD", "en") = "$1,234.50"; for Arabic the code follows the number ("1,234.50 USD"). Digits stay Latin.
func SettingKey ¶
SettingKey is the settings key of theme setting key of theme slug.
func SupportsIdentity ¶ added in v0.3.0
SupportsIdentity is the exported form of supportsIdentity for public handlers (e.g. /site/identity.css).
Types ¶
type Alternate ¶
type Alternate struct {
Locale, Label, URL string
}
Alternate is a page's URL in one locale; Label is the locale's own name.
type BuilderPreviewOptions ¶
type CommentNode ¶
type CommentNode struct {
ID, AuthorName, Body, CreatedAt string
Replies []CommentNode
}
CommentNode is one approved comment.
type CommentsData ¶
type CommentsData struct {
Open bool // the item takes new comments
ContentID string // posted as content_id
Action string // the form's action URL
Back string // posted as _back: the item's path (with its locale prefix)
Count int
Items []CommentNode // approved top-level comments, oldest first, with their replies
}
CommentsData is what a comments component renders for an item. It never holds a commenter's email.
type Context ¶
type Context struct {
Site SiteInfo
Request *http.Request
Kind string
Content *content.Item
Items []content.Item
Term *taxonomy.Term
Pagination Pagination
Query map[string]string
User *auth.User
Theme Info
Extra map[string]any
Locale string
Dir string
Status int
// Alternates are the page in each locale it exists in (hreflang links and language
// switchers); empty when it exists in one locale only.
Alternates []Alternate
}
type InfoLookup ¶
InfoLookup is implemented by the theme service: Lookup reads one installed theme's theme.json (ErrNotFound for unknown or invalid slugs).
type InheritedSource ¶
type InheritedSource struct {
Name string `json:"name"` // e.g. templates/single.html
Before string `json:"before"`
After string `json:"after"` // "" when no theme in the new chain provides it
}
InheritedSource is one inherited file and where it comes from before/after.
type Linker ¶
type Linker struct {
// contains filtered or unexported fields
}
Linker computes public paths (permalinks). It is the single source of URLs for the site router, the url template func and menu items:
page (hierarchical) /parent/child (the front page is /)
other content types /{type}/{slug}
term /{taxonomy}/{term}
type archive /{archive_slug or type}/
Paths are returned unescaped (Arabic slugs stay UTF-8); html/template percent-encodes them in attributes.
func (*Linker) FrontPageID ¶
FrontPageID returns the static front page's content id (setting site.front_page), or "".
func (*Linker) ItemWithFront ¶
ItemWithFront is Item with the front page id already known (renders look it up once). An item in another locale than the site's lives under /<locale>/, and a translation of the front page is that locale's /.
func (*Linker) MenuItem ¶
MenuItem sets it.URL (and its children's) for items that reference a record: kind content (RefID = content id) and term (RefID = term id) always get the permalink, overwriting the menus module's fallback path ("/"+slug is wrong for every type but top-level pages); kind archive (RefID = type) is filled only when empty, so a stored URL wins.
func (*Linker) SiteLocale ¶
SiteLocale is the public site locale (setting site.locale): its URLs carry no locale prefix.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module is the theme kernel.Module: it publishes theme.Service, the menus.resolve_url filter, the Appearance admin screens and the themes/templates API operations. Templates are parsed lazily on first render (after every module has added its funcs).
func (*Module) Migrations ¶
Migrations implements kernel.Module (overrides live on disk).
type Option ¶
type Option func(*Module)
Option configures the module.
func WithLogger ¶
WithLogger sets the logger for render errors (default: Deps.Log).
func WithThemesDir ¶
WithThemesDir sets the themes directory (default: ThemesDir(cfg)).
type Pagination ¶
type Pagination struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
Total int `json:"total"`
Pages int `json:"pages"`
HasPrev bool `json:"has_prev"`
HasNext bool `json:"has_next"`
}
func NewPagination ¶
func NewPagination(page, perPage, total int) Pagination
NewPagination computes page metadata; page and perPage are clamped to ≥ 1.
type ReparentReport ¶
type ReparentReport struct {
Child string `json:"child"`
OldParent string `json:"old_parent"`
NewParent string `json:"new_parent"`
Changed []InheritedSource `json:"changed"` // inherited files whose source theme changes
Missing []string `json:"missing"` // part/component references the new chain cannot resolve
Unchanged int `json:"unchanged"` // inherited files with the same source
Applied bool `json:"applied"` // theme.json was rewritten
BackupPath string `json:"backup,omitempty"`
}
ReparentReport describes the effect of moving Child from OldParent to NewParent.
type Service ¶
type Service interface {
Active(ctx context.Context) Info
List(ctx context.Context) ([]Info, error)
Activate(ctx context.Context, slug string) error
Resolve(req kernel.KindRequest) (templateName string, err error)
Render(ctx context.Context, w http.ResponseWriter, req kernel.KindRequest, tc *Context) error // renders with layout; on template error → 500 page + log
Templates(ctx context.Context) ([]TemplateFile, error)
ReadTemplate(ctx context.Context, name string) (string, error)
TemplateDetails(ctx context.Context, name string) (TemplateDTO, error)
SaveOverride(ctx context.Context, name, body string, draft bool) error
Overrides(ctx context.Context) ([]Override, error)
PublishOverride(ctx context.Context, name string) error
DeleteOverride(ctx context.Context, name string) error
}
type TemplateDTO ¶
type TemplateDTO struct {
Name string `json:"name"`
Source string `json:"source"`
Body string `json:"body"`
Draft *string `json:"draft"`
}
TemplateDTO is one template's sources in API responses; Draft is null when no draft exists.
type TemplateFile ¶
type TemplateFile struct {
Name string `json:"name"`
Path string `json:"path"`
Source string `json:"source"`
}
TemplateFile is a template visible to the theme; Source is "theme", "parent" or "override".
type TemplateListDTO ¶
type TemplateListDTO struct {
Templates []TemplateFile `json:"templates"`
Overrides []Override `json:"overrides"`
}
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package fake holds in-memory implementations of the services the theme engine and the site front controller consume (content, taxonomy, media, menus, redirects, seo), for tests.
|
Package fake holds in-memory implementations of the services the theme engine and the site front controller consume (content, taxonomy, media, menus, redirects, seo), for tests. |