site

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package site holds the website's identity and settings: languages, timezone, branding, contact details, social media profiles and per-language title, tagline, SEO and footer.

Settings are stored as key/value pairs in wt_setting. The scope is "" for site-wide values and a language code for translated text, so new settings need no schema change. They are saved directly, not revisioned.

Every public request reads the settings, often several times, so the Service keeps them in memory: a save in this process replaces them at once, a save by another process shows up within the cache's time to live (see SetCacheTTL).

Index

Constants

View Source
const (
	// CSPOff sends no policy, but the frame-ancestors of Framing: the
	// default.
	CSPOff = "off"

	// CSPReportOnly sends the policy as Content-Security-Policy-Report-Only:
	// browsers block nothing and report what the policy would block, which
	// the site logs. The frame-ancestors of Framing stay enforced.
	CSPReportOnly = "report-only"

	// CSPEnforce sends the policy as Content-Security-Policy: browsers
	// block what it does not allow.
	CSPEnforce = "enforce"
)

The values of Settings.ContentSecurity: whether the site sends a Content-Security-Policy that lets browsers run only the scripts and styles the site serves itself, which blocks most code injected into its pages (cross-site scripting).

View Source
const (
	DefaultFeedSize = 20
	MaxFeedSize     = 100
)

A feed lists DefaultFeedSize of the newest items unless the settings say otherwise (Settings.FeedSize), and never more than MaxFeedSize.

View Source
const (
	DefaultOutputCacheTTL = time.Minute
	DefaultOutputCacheMB  = 32
	MaxOutputCacheTTL     = time.Hour
	MaxOutputCacheMB      = 1024
)

The output cache keeps pages for DefaultOutputCacheTTL in at most DefaultOutputCacheMB megabytes unless the settings say otherwise (see OutputCache); it never keeps them longer than MaxOutputCacheTTL or in more than MaxOutputCacheMB.

View Source
const (
	// FramingSameOrigin lets only the site itself frame its pages: the
	// default.
	FramingSameOrigin = "same-origin"

	// FramingAny lets every site frame the pages, for example to embed them.
	FramingAny = "any"

	// FramingNone lets no site frame the pages, not even the site itself.
	FramingNone = "none"
)

The values of Settings.Framing: which sites may show the site's pages in a frame, such as an iframe. Pages that only the site itself may frame cannot be laid over another site to trick visitors into clicking (clickjacking).

View Source
const MaxTrashDays = 3650

MaxTrashDays is the longest TrashDays accepted: ten years.

Variables

View Source
var ErrCSPSource = errors.New("invalid_csp_source")

ErrCSPSource is a source a Content-Security-Policy may not get from the settings, a theme or the configuration (see CheckCSPSources).

View Source
var ErrInvalid = errors.New("invalid_site_settings")

ErrInvalid is a settings value the site cannot work with, such as an unknown time zone, a language list without the default language or a malformed e-mail address.

View Source
var ErrProfile = errors.New("invalid_site_profile")

ErrProfile is returned for a profile on an unknown network, or with an address that is not a web address.

View Source
var ErrReservedLocale = errors.New("reserved_locale")

ErrReservedLocale is a language whose code is the first segment of an address the site serves itself, such as the admin's at /en: its pages, at /<code>/..., could not be reached (see Service.ReserveLocales).

View Source
var Networks = []string{
	"facebook",
	"instagram",
	"linkedin",
	"x",
	"mastodon",
	"bluesky",
	"threads",
	"youtube",
	"tiktok",
	"pinterest",
	"github",
	"whatsapp",
	"telegram",
}

Networks are the networks the site can have a profile on, in the order the admin and templates show them.

Functions

func CheckCSPSources

func CheckCSPSources(directive string, sources []string) error

CheckCSPSources reports whether sources may be added to directive of the site's Content-Security-Policy, from the settings, a theme (theme.json's "csp") or the configuration. The directive must be one that says where pages load things from: connect-src, font-src, form-action, frame-src, img-src, manifest-src, media-src, script-src, style-src or worker-src. Each source must be one of:

  • an address, such as https://www.youtube-nocookie.com or https://*.example.com/embed/, with the scheme http, https, ws or wss;
  • 'self';
  • the schemes https:, wss:, data: or blob:, but not for script-src;
  • the hash of one inline script or style, such as 'sha256-…', for script-src and style-src only.

Everything else is refused with ErrCSPSource, so no setting can open the policy up to inline code or eval ('unsafe-inline', 'unsafe-eval'), to every site (*) or to a nonce.

func CleanProfileURL

func CleanProfileURL(value string) (string, error)

CleanProfileURL checks a profile address and completes it: an address without a scheme gets https://, so editors can paste "instagram.com/me".

func NetworkName

func NetworkName(network string) string

NetworkName is the English name of a social network, for example "LinkedIn" for "linkedin", or the network itself when it is unknown. Templates translate it with the site's translations.

func ParseCSPSources

func ParseCSPSources(text string) (map[string][]string, error)

ParseCSPSources parses the text of Settings.ContentSecuritySources: one directive per line followed by its sources, such as

frame-src https://www.youtube-nocookie.com https://player.vimeo.com

Blank lines are skipped. A line that CheckCSPSources refuses is an error that wraps ErrCSPSource and quotes the line.

func Schema

func Schema() fs.FS

Schema holds this package's schema files per dialect (see db.ApplySchema).

Types

type Profile

type Profile struct {
	// Network is one of Networks, for example "instagram".
	Network string
	// URL is the profile's web address.
	URL string
}

Profile is one of the site's social media profiles.

type Service

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

Service reads and saves the Site settings, theme values and secrets. It is safe for concurrent use.

func New

func New(database *db.DB) *Service

New returns the settings Service on database, whose schema (Schema) must be applied. Init stores the first settings.

func (*Service) Configuration

func (s *Service) Configuration(ctx context.Context) (locales.Config, error)

Configuration implements locales.Provider with the enabled content languages.

func (*Service) Generation

func (s *Service) Generation() uint64

Generation counts the saves of settings and theme values in this process. It only goes up, so a cache of what is made from them, such as the app's output cache, keeps it with what it made and makes it again once it moved on. Saves by other processes show when the cache's time to live (see SetCacheTTL) has passed, without changing it.

func (*Service) Init

func (s *Service) Init(ctx context.Context, name string, config locales.Config) error

Init stores first settings when none exist yet. Later calls do nothing.

func (*Service) ReserveLocales

func (s *Service) ReserveLocales(codes ...string)

ReserveLocales keeps languages with the given codes, ignoring case, from being enabled: Save refuses them with ErrReservedLocale. The app reserves the first segments of its own addresses (webthings.App.CorePaths), such as the admin's path, /media and, with the content API, /api, whose routes would hide the language's pages. Call it before Init and before the site serves.

func (*Service) ReservedLocale

func (s *Service) ReservedLocale(locales []string) (string, bool)

ReservedLocale returns the first of locales that is reserved (see ReserveLocales), and false when none is.

func (*Service) Save

func (s *Service) Save(ctx context.Context, settings Settings) error

Save validates and replaces all settings.

func (*Service) SaveThemeValues

func (s *Service) SaveThemeValues(ctx context.Context, theme string, values map[string]string) error

SaveThemeValues replaces the stored settings of a theme.

func (*Service) Secret

func (s *Service) Secret(ctx context.Context, name string) ([]byte, error)

Secret returns a random 32-byte key that belongs to this site, creating it on first use, for example to sign image variant URLs. Every process of the site gets the same key; it is never shown in the settings.

func (*Service) SetCacheTTL

func (s *Service) SetCacheTTL(ttl time.Duration)

SetCacheTTL sets how long settings are kept in memory (30 seconds by default). Saves in this process apply at once; the time to live bounds how long saves by other processes take to show up. Zero or less disables the cache.

func (*Service) SetTheme

func (s *Service) SetTheme(ctx context.Context, theme string) error

SetTheme makes theme the active theme.

func (*Service) Settings

func (s *Service) Settings(ctx context.Context) (Settings, error)

Settings returns the current settings with all translations.

func (*Service) Snapshot

func (s *Service) Snapshot(ctx context.Context) (*Snapshot, error)

Snapshot returns the settings and theme values to read: those of the request ctx belongs to (see WithSnapshot), otherwise the current ones. It copies nothing; see Snapshot for what readers may not do. Code that changes the settings it reads, such as a settings form, uses Settings and ThemeValues instead, which give copies of the current ones.

func (*Service) ThemeValues

func (s *Service) ThemeValues(ctx context.Context, theme string) (map[string]string, error)

ThemeValues returns the stored settings of a theme.

func (*Service) WithSnapshot

func (s *Service) WithSnapshot(ctx context.Context) context.Context

WithSnapshot returns ctx with the current Snapshot, for a request: every Snapshot call with ctx, or a context made from it, gives that one, so the settings are the same throughout the request, also when an editor saves meanwhile. When the settings cannot be read, ctx is returned as it is, and Snapshot reads them itself. App does this for every request to the site, the admin and the modules' actions.

type Settings

type Settings struct {
	DefaultLocale string   `setting:"default_locale"`
	Locales       []string `setting:"locales"`
	Timezone      string   `setting:"timezone"`
	// Theme is the active theme's folder name; empty uses the first theme.
	Theme string `setting:"theme"`

	LogoMediaID        string `setting:"logo_media_id"`
	FaviconMediaID     string `setting:"favicon_media_id"`
	SocialImageMediaID string `setting:"social_image_media_id"`

	Organisation string `setting:"organisation"`
	Email        string `setting:"email"`
	Phone        string `setting:"phone"`
	Address      string `setting:"address"`

	// FeedSize is how many of the newest items each feed of the site lists,
	// such as the posts of a news page; zero is DefaultFeedSize. See
	// FeedLimit.
	FeedSize int `setting:"feed_size"`

	// Profiles are the site's social media profiles, in the order of
	// Networks. Each is stored as its own setting, profile_<network>.
	Profiles []Profile

	// CompressionOff, PageMaxAge and PageStale tune how the site is served;
	// see Compress and PageCache. Responses are compressed unless
	// CompressionOff is set; the cache times are seconds.
	CompressionOff bool `setting:"compression_off"`
	PageMaxAge     int  `setting:"page_max_age"`
	PageStale      int  `setting:"page_stale"`

	// OutputCacheOff, OutputCacheTTL and OutputCacheMB tune the output
	// cache, which keeps public pages for visitors in memory; see
	// OutputCache. It is on unless OutputCacheOff is set; zero times and
	// sizes are the defaults.
	OutputCacheOff bool `setting:"output_cache_off"`
	OutputCacheTTL int  `setting:"output_cache_ttl"`
	OutputCacheMB  int  `setting:"output_cache_mb"`

	// Framing is which sites may show the site's pages in a frame:
	// FramingSameOrigin, FramingAny or FramingNone; empty is
	// FramingSameOrigin. See FramingPolicy.
	Framing string `setting:"framing"`

	// ContentSecurity is whether the site sends a Content-Security-Policy:
	// CSPOff, CSPReportOnly or CSPEnforce; empty is CSPOff. See
	// ContentSecurityPolicy.
	ContentSecurity string `setting:"content_security"`
	// ContentSecuritySources are sources the policy allows besides the
	// site's own, one directive per line, such as "frame-src
	// https://www.youtube-nocookie.com"; see ParseCSPSources.
	ContentSecuritySources string `setting:"content_security_sources"`

	// Review lists the admin sections, by permission ID, whose revisions
	// need a reviewer's approval before they are published; see Reviewed.
	// Empty, the default, turns the review workflow off everywhere.
	Review []string `setting:"review"`

	// TrashDays is after how many days in the admin's trash items are
	// deleted for good, at most MaxTrashDays; zero, the default, keeps
	// them until someone deletes them. See TrashCutoff.
	TrashDays int `setting:"trash_days"`

	// Setup lists the steps of the admin's setup guide an administrator
	// finished, by ID, such as "site", or skipped, as "skip:" followed by
	// the ID; "done" once the guide is finished. Empty, the default, is a
	// site whose setup has not started.
	Setup []string `setting:"setup"`

	Translations []Translation
	// contains filtered or unexported fields
}

Settings are the site-wide values. Each `setting` tag names a stored key.

func (Settings) Compress

func (s Settings) Compress() bool

Compress reports whether responses are compressed (gzip) for browsers that accept it: the default, unless CompressionOff is set.

func (Settings) ContentSecurityExtra

func (s Settings) ContentSecurityExtra() map[string][]string

ContentSecurityExtra are the sources ContentSecuritySources adds to the policy, by directive; lines that are not allowed are left out, which only happens to settings saved around Save.

func (Settings) ContentSecurityPolicy

func (s Settings) ContentSecurityPolicy() string

ContentSecurityPolicy is whether the site sends a Content-Security-Policy: ContentSecurity, or CSPOff when it is empty or unknown.

func (Settings) FeedLimit

func (s Settings) FeedLimit() int

FeedLimit is how many of the newest items each feed of the site lists, such as the posts in a news page's Atom and RSS feeds: FeedSize, or DefaultFeedSize when it is not set.

func (Settings) FramingPolicy

func (s Settings) FramingPolicy() string

FramingPolicy is which sites may frame the site's pages: Framing, or FramingSameOrigin when it is empty or unknown.

func (Settings) LocaleConfig

func (s Settings) LocaleConfig() locales.Config

LocaleConfig returns the content languages of the settings in the form the locales package checks and services use.

func (Settings) Location

func (s Settings) Location() *time.Location

Location is the site's timezone, for showing and reading dates and times. Loaded settings parse it once, so calling it on every request costs nothing; settings whose Timezone was changed since, or that were made in code, parse it on each call. An empty or unknown Timezone is UTC.

func (Settings) OutputCache

func (s Settings) OutputCache() (ttl time.Duration, maxBytes int64)

OutputCache is how long the output cache keeps a public page for visitors in memory and how many bytes it keeps at most: DefaultOutputCacheTTL and DefaultOutputCacheMB unless set; a ttl of zero when OutputCacheOff is set. Changes made in this process show at once; the time bounds how long a page shows what changed without a save, such as content published at its scheduled time, and changes made by other processes.

func (Settings) PageCache

func (s Settings) PageCache() (maxAge, stale int)

PageCache is how long, in seconds, browsers and caches may keep a public page for visitors (maxAge; 0, the default, has them ask the site every time) and how long after that they may still show it while fetching a fresh one (stale, for stale-while-revalidate).

func (Settings) Profile

func (s Settings) Profile(network string) string

Profile returns the address of the site's profile on network, or "".

func (Settings) Reviewed

func (s Settings) Reviewed(section string) bool

Reviewed reports whether the review workflow is on for an admin section, by its permission ID, such as "pages" or "news": its revisions are then published only after a reviewer approved them (see content.WithReview).

func (Settings) Text

func (s Settings) Text(locale string) Translation

Text returns the translation for locale, falling back to an empty one.

func (Settings) TrashCutoff

func (s Settings) TrashCutoff(now time.Time) (cutoff time.Time, ok bool)

TrashCutoff is the deletion time before which items in the admin's trash are deleted for good at now: TrashDays days before now. ok is false when TrashDays is zero, the default, which keeps items in the trash until someone deletes them.

func (Settings) WithText

func (s Settings) WithText(translation Translation) []Translation

WithText returns the translations with locale replaced.

type Snapshot

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

Snapshot is everything in wt_setting as one load read it: the settings and the values of each theme. The Service keeps one and gives it to every reader until a save, or the end of the cache's time to live, makes a new one; a Snapshot never changes. What its methods return is its own, to read and never to change: Service.Settings gives a copy to change.

func (*Snapshot) Settings

func (s *Snapshot) Settings() Settings

Settings are the snapshot's settings. Their lists (Locales, Profiles, Review and Translations) are the snapshot's own: read them, never change them.

func (*Snapshot) ThemeValues

func (s *Snapshot) ThemeValues(theme string) map[string]string

ThemeValues are the stored values of a theme, nil when it has none; the map is the snapshot's own, to read and never to change.

type Translation

type Translation struct {
	Locale         string
	Title          string `setting:"title"`
	Tagline        string `setting:"tagline"`
	SEOTitle       string `setting:"seo_title"`
	SEODescription string `setting:"seo_description"`
	// Footer is Markdown.
	Footer string `setting:"footer"`
}

Translation is the text of one language; its scope is the locale.

Directories

Path Synopsis
Package siteadmin is the Site settings section of the admin: the site's languages, time zone, texts, social media profiles, performance, security, review and trash settings, the Theme screen where editors choose the theme and set its values, and the Backup screen where administrators download the site as a zip file.
Package siteadmin is the Site settings section of the admin: the site's languages, time zone, texts, social media profiles, performance, security, review and trash settings, the Theme screen where editors choose the theme and set its values, and the Backup screen where administrators download the site as a zip file.

Jump to

Keyboard shortcuts

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