models

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultLicenseKey = "cc-by-4.0"

DefaultLicenseKey is the license key used by the init wizard when no choice is provided.

View Source
const RoleAuthor = "author"

RoleAuthor is the simple role name for a primary author.

Variables

View Source
var CReDiTRoles = []string{
	"conceptualization",
	"data-curation",
	"formal-analysis",
	"funding-acquisition",
	"investigation",
	"methodology",
	"project-administration",
	"resources",
	"software",
	"supervision",
	"validation",
	"visualization",
	"writing-original-draft",
	"writing-review-editing",
}

CReDiTRoles defines standard CReDiT contributor roles taxonomy ANSI/NISO standard Z39.104-2022

View Source
var DefaultSharePlatformOrder = []string{"twitter", "bluesky", "linkedin", "whatsapp", "facebook", "telegram", "pinterest", "reddit", "hacker_news", "email", "copy"}

DefaultSharePlatformOrder defines the built-in share buttons in the default order.

View Source
var DefaultWellKnownAutoGenerate = []string{
	"host-meta",
	"host-meta.json",
	"webfinger",
	"nodeinfo",
	"time",
}

DefaultWellKnownAutoGenerate lists the default auto-generated entries.

View Source
var KnownExtensions = map[string]bool{
	".md": true, ".markdown": true, ".mdown": true, ".mkd": true,
	".html": true, ".htm": true,
	".txt": true, ".text": true,
	".rst": true, ".asciidoc": true, ".adoc": true,
}

KnownExtensions contains file extensions that should be stripped from filenames. Extensions not in this list are treated as part of the filename.

View Source
var LicenseOptions = []LicenseOption{
	{Key: "all-rights-reserved", Name: "All rights reserved", Description: "No reuse without permission", URL: "", Recommended: false},
	{Key: "cc-by-4.0", Name: "Creative Commons Attribution 4.0", Description: "Reuse with attribution", URL: "https://creativecommons.org/licenses/by/4.0/", Recommended: true},
	{Key: "cc-by-sa-4.0", Name: "Creative Commons Attribution-ShareAlike 4.0", Description: "Reuse with attribution and share-alike", URL: "https://creativecommons.org/licenses/by-sa/4.0/", Recommended: false},
	{Key: "cc-by-nc-4.0", Name: "Creative Commons Attribution-NonCommercial 4.0", Description: "Reuse non-commercially with attribution", URL: "https://creativecommons.org/licenses/by-nc/4.0/", Recommended: false},
	{Key: "cc-by-nd-4.0", Name: "Creative Commons Attribution-NoDerivatives 4.0", Description: "Reuse with attribution, no derivatives", URL: "https://creativecommons.org/licenses/by-nd/4.0/", Recommended: false},
	{Key: "cc-by-nc-sa-4.0", Name: "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", Description: "Non-commercial reuse with attribution and share-alike", URL: "https://creativecommons.org/licenses/by-nc-sa/4.0/", Recommended: false},
	{Key: "mit", Name: "MIT License", Description: "Permissive open source license", URL: "https://opensource.org/licenses/MIT", Recommended: false},
}

LicenseOptions lists the built-in license choices in display order.

View Source
var SimpleRoles = []string{
	RoleAuthor,
	"editor",
	"designer",
	"maintainer",
	"contributor",
	"reviewer",
	"translator",
}

SimpleRoles defines common roles for blog/content sites

Functions

func DefaultCardMappings added in v0.7.0

func DefaultCardMappings() map[string]string

DefaultCardMappings returns the default template-to-card mappings. These are the built-in mappings that user config merges with.

func LayoutToTemplate added in v0.4.0

func LayoutToTemplate(layout string) string

LayoutToTemplate converts a layout name to a template file path. Layout names map to templates as follows:

  • "docs" -> "layouts/docs.html"
  • "blog" -> "post.html"
  • "landing" -> "layouts/landing.html"
  • "bare" -> "layouts/bare.html"
  • "" (empty) -> "post.html" (default)

func LicenseKeys added in v0.7.0

func LicenseKeys() []string

LicenseKeys returns the supported license keys in display order.

func Slugify added in v0.6.0

func Slugify(s string) string

Slugify converts a string to a URL-safe slug. It converts to lowercase, replaces non-alphanumeric characters with hyphens, collapses multiple hyphens, and trims leading/trailing hyphens.

func StripKnownExtension added in v0.6.0

func StripKnownExtension(filename string) string

StripKnownExtension removes only recognized file extensions from filenames. For example: "post.md" -> "post", but "v1.2.3" -> "v1.2.3"

func ValidateAuthors added in v0.7.0

func ValidateAuthors(authors map[string]Author) error

ValidateAuthors validates a collection of authors and enforces business rules

Types

type AlternateFeed added in v0.3.0

type AlternateFeed struct {
	// Type is the feed type: "rss", "atom", or "json"
	Type string `json:"type" yaml:"type" toml:"type"`

	// Title is the human-readable feed title (e.g., "RSS Feed")
	Title string `json:"title" yaml:"title" toml:"title"`

	// Href is the URL path to the feed (e.g., "/rss.xml")
	Href string `json:"href" yaml:"href" toml:"href"`
}

AlternateFeed configures a <link rel="alternate"> tag for feed discovery.

func (*AlternateFeed) GetMIMEType added in v0.3.0

func (f *AlternateFeed) GetMIMEType() string

GetMIMEType returns the MIME type for this feed type.

type AssetsConfig added in v0.7.0

type AssetsConfig struct {
	// Mode controls how external assets are handled:
	// - "cdn": Always load from external CDN (default, no download)
	// - "self-hosted": Download and serve from local output/assets/vendor/
	// - "auto": Use self-hosted if assets are cached, fall back to CDN
	Mode string `json:"mode,omitempty" yaml:"mode,omitempty" toml:"mode,omitempty"`

	// CacheDir is the directory for caching downloaded assets (default: ".markata/assets-cache")
	CacheDir string `json:"cache_dir,omitempty" yaml:"cache_dir,omitempty" toml:"cache_dir,omitempty"`

	// VerifyIntegrity enables SRI hash verification for downloaded assets (default: true)
	VerifyIntegrity *bool `json:"verify_integrity,omitempty" yaml:"verify_integrity,omitempty" toml:"verify_integrity,omitempty"`

	// OutputDir is the subdirectory in output for vendor assets (default: "assets/vendor")
	OutputDir string `json:"output_dir,omitempty" yaml:"output_dir,omitempty" toml:"output_dir,omitempty"`
}

AssetsConfig configures external CDN asset handling for self-hosting. When mode is "self-hosted", external assets (GLightbox, HTMX, Mermaid, etc.) are downloaded at build time and served from the site itself.

func NewAssetsConfig added in v0.7.0

func NewAssetsConfig() AssetsConfig

NewAssetsConfig creates a new AssetsConfig with default values.

func (*AssetsConfig) GetCacheDir added in v0.7.0

func (a *AssetsConfig) GetCacheDir() string

GetCacheDir returns the cache directory, with default if not set.

func (*AssetsConfig) GetOutputDir added in v0.7.0

func (a *AssetsConfig) GetOutputDir() string

GetOutputDir returns the output directory for vendor assets.

func (*AssetsConfig) IsSelfHosted added in v0.7.0

func (a *AssetsConfig) IsSelfHosted() bool

IsSelfHosted returns true if assets should be self-hosted.

func (*AssetsConfig) IsVerifyIntegrityEnabled added in v0.7.0

func (a *AssetsConfig) IsVerifyIntegrityEnabled() bool

IsVerifyIntegrityEnabled returns whether integrity verification is enabled. Defaults to true if not explicitly set.

type Author added in v0.7.0

type Author struct {
	ID      string            `json:"id" yaml:"id" toml:"id"`
	Name    string            `json:"name" yaml:"name" toml:"name"`
	Bio     *string           `json:"bio,omitempty" yaml:"bio,omitempty" toml:"bio,omitempty"`
	Email   *string           `json:"email,omitempty" yaml:"email,omitempty" toml:"email,omitempty"`
	Avatar  *string           `json:"avatar,omitempty" yaml:"avatar,omitempty" toml:"avatar,omitempty"`
	URL     *string           `json:"url,omitempty" yaml:"url,omitempty" toml:"url,omitempty"`
	Social  map[string]string `json:"social,omitempty" yaml:"social,omitempty" toml:"social,omitempty"`
	Guest   bool              `json:"guest,omitempty" yaml:"guest,omitempty" toml:"guest,omitempty"`
	Active  bool              `json:"active,omitempty" yaml:"active,omitempty" toml:"active,omitempty"`
	Default bool              `json:"default,omitempty" yaml:"default,omitempty" toml:"default,omitempty"`

	// Level 1: CReDiT academic roles
	Contributions []string `json:"contributions,omitempty" yaml:"contributions,omitempty" toml:"contributions,omitempty"`

	// Level 2: Simple role system
	Role *string `json:"role,omitempty" yaml:"role,omitempty" toml:"role,omitempty"`

	// Level 3: Custom free-form contribution
	Contribution *string `json:"contribution,omitempty" yaml:"contribution,omitempty" toml:"contribution,omitempty"`

	// Details is an optional per-post description of what the author did.
	// Typically set via frontmatter overrides, displayed as a tooltip on hover.
	Details *string `json:"details,omitempty" yaml:"details,omitempty" toml:"details,omitempty"`
}

Author represents an author or contributor to content

func GetDefaultAuthor added in v0.7.0

func GetDefaultAuthor(authors map[string]Author) (defaultAuthor *Author, defaultID string)

GetDefaultAuthor returns the author marked as default

func (*Author) GetRoleDisplay added in v0.7.0

func (a *Author) GetRoleDisplay() string

GetRoleDisplay returns a human-readable display of the author's role/contribution

func (*Author) HasContribution added in v0.7.0

func (a *Author) HasContribution(contribution string) bool

HasContribution checks if author has a specific contribution type

func (*Author) IsPrimaryContributor added in v0.7.0

func (a *Author) IsPrimaryContributor() bool

IsPrimaryContributor checks if author has writing/conceptualization roles

func (*Author) Validate added in v0.7.0

func (a *Author) Validate() error

ValidateAuthor validates author data according to the specified level

func (*Author) ValidateCReDiTContributions added in v0.7.0

func (a *Author) ValidateCReDiTContributions() error

ValidateCReDiTContributions checks if all contributions are valid CReDiT roles

func (*Author) ValidateSimpleRole added in v0.7.0

func (a *Author) ValidateSimpleRole() error

ValidateSimpleRole checks if role is in simple roles list

type AuthorsConfig added in v0.7.0

type AuthorsConfig struct {
	// GeneratePages enables automatic author bio page generation (default: false)
	GeneratePages bool `json:"generate_pages,omitempty" yaml:"generate_pages,omitempty" toml:"generate_pages,omitempty"`

	// URLPattern defines the URL pattern for author pages (default: "/authors/{author}/")
	URLPattern string `json:"url_pattern,omitempty" yaml:"url_pattern,omitempty" toml:"url_pattern,omitempty"`

	// FeedsEnabled enables author-specific RSS/Atom feeds (default: false)
	FeedsEnabled bool `json:"feeds_enabled,omitempty" yaml:"feeds_enabled,omitempty" toml:"feeds_enabled,omitempty"`

	// Authors is a map of author configurations keyed by author ID
	Authors map[string]Author `json:"authors,omitempty" yaml:"authors,omitempty" toml:"authors,omitempty"`
}

AuthorsConfig configures multi-author support for the site.

type BackgroundConfig added in v0.6.0

type BackgroundConfig struct {
	// Enabled controls whether background decorations are active (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Backgrounds is the list of background elements to render
	Backgrounds []BackgroundElement `json:"backgrounds,omitempty" yaml:"backgrounds,omitempty" toml:"backgrounds,omitempty"`

	// Scripts is a list of script URLs to include for background functionality
	// Example: ["/static/js/snow-fall.js"]
	Scripts []string `json:"scripts,omitempty" yaml:"scripts,omitempty" toml:"scripts,omitempty"`

	// CSS is custom CSS for styling background elements
	CSS string `json:"css,omitempty" yaml:"css,omitempty" toml:"css,omitempty"`

	// ArticleBg is the background color for article/content areas (default: uses --color-background)
	// This helps ensure content is readable over decorative backgrounds.
	// Example: "rgba(255, 255, 255, 0.95)" or "#ffffff"
	ArticleBg string `json:"article_bg,omitempty" yaml:"article_bg,omitempty" toml:"article_bg,omitempty"`

	// ArticleBlurEnabled controls whether backdrop blur is applied to article areas (default: false)
	// When false, the ArticleBlur value is ignored even if set.
	ArticleBlurEnabled *bool `json:"article_blur_enabled,omitempty" yaml:"article_blur_enabled,omitempty" toml:"article_blur_enabled,omitempty"`

	// ArticleBlur is the backdrop blur amount for article areas (default: "0px")
	// Example: "8px" or "12px" for a frosted glass effect
	ArticleBlur string `json:"article_blur,omitempty" yaml:"article_blur,omitempty" toml:"article_blur,omitempty"`

	// ArticleShadow is the box-shadow for article areas
	// Example: "0 4px 20px rgba(0, 0, 0, 0.3)"
	ArticleShadow string `json:"article_shadow,omitempty" yaml:"article_shadow,omitempty" toml:"article_shadow,omitempty"`

	// ArticleBorder is the border style for article areas
	// Example: "1px solid rgba(255, 255, 255, 0.1)"
	ArticleBorder string `json:"article_border,omitempty" yaml:"article_border,omitempty" toml:"article_border,omitempty"`

	// ArticleRadius is the border-radius for article areas (default: uses --radius-lg)
	// Example: "12px" or "1rem"
	ArticleRadius string `json:"article_radius,omitempty" yaml:"article_radius,omitempty" toml:"article_radius,omitempty"`
}

BackgroundConfig configures multi-layered background decorations for pages. Background elements are rendered as fixed-position layers behind the main content.

func NewBackgroundConfig added in v0.6.0

func NewBackgroundConfig() BackgroundConfig

NewBackgroundConfig creates a new BackgroundConfig with default values.

func (*BackgroundConfig) IsArticleBlurEnabled added in v0.6.0

func (b *BackgroundConfig) IsArticleBlurEnabled() bool

IsArticleBlurEnabled returns whether backdrop blur is enabled for article areas. Defaults to false if not explicitly set.

func (*BackgroundConfig) IsEnabled added in v0.6.0

func (b *BackgroundConfig) IsEnabled() bool

IsEnabled returns whether background decorations are enabled. Defaults to false if not explicitly set.

type BackgroundElement added in v0.6.0

type BackgroundElement struct {
	// HTML is the HTML content for this background layer
	// Example: '<snow-fall count="200"></snow-fall>'
	HTML string `json:"html" yaml:"html" toml:"html"`

	// ZIndex controls the stacking order of this layer (default: -1)
	// Negative values place the layer behind content, positive values in front
	ZIndex int `json:"z_index,omitempty" yaml:"z_index,omitempty" toml:"z_index,omitempty"`
}

BackgroundElement represents a single background decoration layer.

type BareLayoutConfig added in v0.4.0

type BareLayoutConfig struct {
	// ContentMaxWidth is the maximum width of the content area (default: "100%")
	ContentMaxWidth string `json:"content_max_width,omitempty" yaml:"content_max_width,omitempty" toml:"content_max_width,omitempty"`
}

BareLayoutConfig configures the bare layout. This is a minimal layout with no chrome - just the content.

type BlogLayoutConfig added in v0.4.0

type BlogLayoutConfig struct {
	// ContentMaxWidth is the maximum width of the content area (default: "720px")
	ContentMaxWidth string `json:"content_max_width,omitempty" yaml:"content_max_width,omitempty" toml:"content_max_width,omitempty"`

	// ShowToc enables table of contents for blog posts (default: false)
	ShowToc *bool `json:"show_toc,omitempty" yaml:"show_toc,omitempty" toml:"show_toc,omitempty"`

	// TocPosition controls TOC placement: "left" or "right" (default: "right")
	TocPosition string `json:"toc_position,omitempty" yaml:"toc_position,omitempty" toml:"toc_position,omitempty"`

	// TocWidth is the width of the table of contents (default: "200px")
	TocWidth string `json:"toc_width,omitempty" yaml:"toc_width,omitempty" toml:"toc_width,omitempty"`

	// HeaderStyle controls the header appearance: "full", "minimal", "transparent", "none" (default: "full")
	HeaderStyle string `json:"header_style,omitempty" yaml:"header_style,omitempty" toml:"header_style,omitempty"`

	// FooterStyle controls the footer appearance: "full", "minimal", "none" (default: "full")
	FooterStyle string `json:"footer_style,omitempty" yaml:"footer_style,omitempty" toml:"footer_style,omitempty"`

	// ShowAuthor displays the post author (default: true)
	ShowAuthor *bool `json:"show_author,omitempty" yaml:"show_author,omitempty" toml:"show_author,omitempty"`

	// ShowDate displays the post date (default: true)
	ShowDate *bool `json:"show_date,omitempty" yaml:"show_date,omitempty" toml:"show_date,omitempty"`

	// ShowTags displays the post tags (default: true)
	ShowTags *bool `json:"show_tags,omitempty" yaml:"show_tags,omitempty" toml:"show_tags,omitempty"`

	// ShowReadingTime displays estimated reading time (default: true)
	ShowReadingTime *bool `json:"show_reading_time,omitempty" yaml:"show_reading_time,omitempty" toml:"show_reading_time,omitempty"`

	// ShowPrevNext displays previous/next post navigation (default: true)
	ShowPrevNext *bool `json:"show_prev_next,omitempty" yaml:"show_prev_next,omitempty" toml:"show_prev_next,omitempty"`
}

BlogLayoutConfig configures the blog layout. This is a single-column layout optimized for reading long-form content.

func (*BlogLayoutConfig) IsShowAuthor added in v0.4.0

func (b *BlogLayoutConfig) IsShowAuthor() bool

IsShowAuthor returns whether to show the author.

func (*BlogLayoutConfig) IsShowDate added in v0.4.0

func (b *BlogLayoutConfig) IsShowDate() bool

IsShowDate returns whether to show the date.

func (*BlogLayoutConfig) IsShowPrevNext added in v0.4.0

func (b *BlogLayoutConfig) IsShowPrevNext() bool

IsShowPrevNext returns whether to show previous/next navigation.

func (*BlogLayoutConfig) IsShowReadingTime added in v0.4.0

func (b *BlogLayoutConfig) IsShowReadingTime() bool

IsShowReadingTime returns whether to show reading time.

func (*BlogLayoutConfig) IsShowTags added in v0.4.0

func (b *BlogLayoutConfig) IsShowTags() bool

IsShowTags returns whether to show tags.

func (*BlogLayoutConfig) IsShowToc added in v0.4.0

func (b *BlogLayoutConfig) IsShowToc() bool

IsShowToc returns whether to show the table of contents.

type BlogPosting added in v0.3.0

type BlogPosting struct {
	Context          string       `json:"@context"`
	Type             string       `json:"@type"`
	Headline         string       `json:"headline"`
	Description      string       `json:"description,omitempty"`
	DatePublished    string       `json:"datePublished,omitempty"`
	DateModified     string       `json:"dateModified,omitempty"`
	Author           *SchemaAgent `json:"author,omitempty"`
	Publisher        *SchemaAgent `json:"publisher,omitempty"`
	MainEntityOfPage *WebPage     `json:"mainEntityOfPage,omitempty"`
	Image            string       `json:"image,omitempty"`
	Keywords         []string     `json:"keywords,omitempty"`
	URL              string       `json:"url,omitempty"`
}

BlogPosting represents a Schema.org BlogPosting for JSON-LD.

func NewBlogPosting added in v0.3.0

func NewBlogPosting(headline, url string) *BlogPosting

NewBlogPosting creates a new BlogPosting with required fields.

type BlogrollCategory added in v0.5.0

type BlogrollCategory struct {
	// Name is the category name
	Name string `json:"name"`

	// Slug is the URL-safe category identifier
	Slug string `json:"slug"`

	// Feeds are the feeds in this category
	Feeds []*ExternalFeed `json:"feeds"`
}

BlogrollCategory groups feeds by category for display.

type BlogrollConfig added in v0.5.0

type BlogrollConfig struct {
	// Enabled controls whether blogroll functionality is active (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// BlogrollSlug is the URL path for the blogroll page (default: "blogroll")
	// This generates the page at /{blogroll_slug}/index.html
	BlogrollSlug string `json:"blogroll_slug" yaml:"blogroll_slug" toml:"blogroll_slug"`

	// ReaderSlug is the URL path for the reader page (default: "reader")
	// This generates the page at /{reader_slug}/index.html
	ReaderSlug string `json:"reader_slug" yaml:"reader_slug" toml:"reader_slug"`

	// CacheDir is the directory for caching fetched feeds (default: "cache/blogroll")
	CacheDir string `json:"cache_dir" yaml:"cache_dir" toml:"cache_dir"`

	// CacheDuration is how long to cache fetched feeds (default: "1h")
	CacheDuration string `json:"cache_duration" yaml:"cache_duration" toml:"cache_duration"`

	// Timeout is the HTTP request timeout in seconds (default: 30)
	Timeout int `json:"timeout" yaml:"timeout" toml:"timeout"`

	// ConcurrentRequests is the max concurrent feed fetches (default: 5)
	ConcurrentRequests int `json:"concurrent_requests" yaml:"concurrent_requests" toml:"concurrent_requests"`

	// MaxEntriesPerFeed limits entries fetched per feed (default: 50)
	MaxEntriesPerFeed int `json:"max_entries_per_feed" yaml:"max_entries_per_feed" toml:"max_entries_per_feed"`

	// ItemsPerPage is the number of entries per page on the reader page (default: 50)
	ItemsPerPage int `json:"items_per_page" yaml:"items_per_page" toml:"items_per_page"`

	// OrphanThreshold is the minimum entries for a separate page (default: 3)
	OrphanThreshold int `json:"orphan_threshold" yaml:"orphan_threshold" toml:"orphan_threshold"`

	// PaginationType specifies the pagination strategy (manual, htmx, js)
	PaginationType PaginationType `json:"pagination_type" yaml:"pagination_type" toml:"pagination_type"`

	// FallbackImageService is an optional URL template for generating fallback images
	// for entries without images. Use {url} as placeholder for the entry URL.
	// Example: "https://shots.example.com/shot/?url={url}&width=1200"
	// If empty, no fallback images are generated (default: "")
	FallbackImageService string `json:"fallback_image_service" yaml:"fallback_image_service" toml:"fallback_image_service"`

	// Feeds is the list of RSS/Atom feeds to fetch
	Feeds []ExternalFeedConfig `json:"feeds" yaml:"feeds" toml:"feeds"`

	// Templates configures custom templates for blogroll pages
	Templates BlogrollTemplates `json:"templates" yaml:"templates" toml:"templates"`
}

BlogrollConfig configures the blogroll and RSS reader functionality.

func NewBlogrollConfig added in v0.5.0

func NewBlogrollConfig() BlogrollConfig

NewBlogrollConfig creates a new BlogrollConfig with default values.

type BlogrollTemplates added in v0.5.0

type BlogrollTemplates struct {
	// Blogroll is the template for the /blogroll page
	Blogroll string `json:"blogroll" yaml:"blogroll" toml:"blogroll"`

	// Reader is the template for the /reader page
	Reader string `json:"reader" yaml:"reader" toml:"reader"`
}

BlogrollTemplates specifies custom templates for blogroll pages.

type BridgeFiltersConfig added in v0.5.0

type BridgeFiltersConfig struct {
	// Platforms limits which platforms to accept (empty = all enabled)
	Platforms []string `json:"platforms" yaml:"platforms" toml:"platforms"`

	// InteractionTypes limits which interaction types to accept (empty = all)
	// Valid values: "like", "repost", "reply", "bookmark", "mention"
	InteractionTypes []string `json:"interaction_types" yaml:"interaction_types" toml:"interaction_types"`

	// MinContentLength filters out mentions with content shorter than this
	MinContentLength int `json:"min_content_length" yaml:"min_content_length" toml:"min_content_length"`

	// BlockedDomains is a list of domains to reject mentions from
	BlockedDomains []string `json:"blocked_domains" yaml:"blocked_domains" toml:"blocked_domains"`
}

BridgeFiltersConfig configures filtering for bridged webmentions.

type BridgesConfig added in v0.5.0

type BridgesConfig struct {
	// Enabled controls whether bridging detection is active (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// BridgyFediverse enables Bridgy Fed integration (default: true when bridges enabled)
	BridgyFediverse bool `json:"bridgy_fediverse" yaml:"bridgy_fediverse" toml:"bridgy_fediverse"`

	// Platform-specific controls
	Bluesky  bool `json:"bluesky" yaml:"bluesky" toml:"bluesky"`
	Twitter  bool `json:"twitter" yaml:"twitter" toml:"twitter"`
	Mastodon bool `json:"mastodon" yaml:"mastodon" toml:"mastodon"`
	GitHub   bool `json:"github" yaml:"github" toml:"github"`
	Flickr   bool `json:"flickr" yaml:"flickr" toml:"flickr"`

	// Filters configures filtering of bridged mentions
	Filters BridgeFiltersConfig `json:"filters" yaml:"filters" toml:"filters"`
}

BridgesConfig configures social media bridging services.

func NewBridgesConfig added in v0.5.0

func NewBridgesConfig() BridgesConfig

NewBridgesConfig creates a new BridgesConfig with default values.

type BundleConfig added in v0.7.0

type BundleConfig struct {
	// Name is the bundle identifier (e.g., "main", "critical")
	Name string `json:"name" yaml:"name" toml:"name"`

	// Sources is a list of CSS file paths or glob patterns to include
	// Files are concatenated in the order specified
	Sources []string `json:"sources" yaml:"sources" toml:"sources"`

	// Output is the output file path relative to output_dir (e.g., "css/bundle.css")
	Output string `json:"output" yaml:"output" toml:"output"`
}

BundleConfig defines a single CSS bundle.

type CLIRendererConfig added in v0.7.0

type CLIRendererConfig struct {
	// MMDCPath is the path to the mmdc binary. If empty, looks for it in PATH.
	MMDCPath string `json:"mmdc_path" yaml:"mmdc_path" toml:"mmdc_path"`

	// ExtraArgs are additional command-line arguments passed to mmdc
	ExtraArgs string `json:"extra_args" yaml:"extra_args" toml:"extra_args"`
}

CLIRendererConfig configures the CLI-based renderer (npm mmdc)

type CSSBundleConfig added in v0.7.0

type CSSBundleConfig struct {
	// Enabled controls whether CSS bundling is active (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Bundles is list of bundle configurations
	Bundles []BundleConfig `json:"bundles" yaml:"bundles" toml:"bundles"`

	// Exclude is a list of CSS file patterns to exclude from bundling
	Exclude []string `json:"exclude" yaml:"exclude" toml:"exclude"`

	// Minify controls whether bundled CSS is minified (default: false)
	// Note: minification is not yet implemented
	Minify bool `json:"minify" yaml:"minify" toml:"minify"`

	// AddSourceComments adds comments indicating source files in bundles (default: true)
	AddSourceComments *bool `json:"add_source_comments,omitempty" yaml:"add_source_comments,omitempty" toml:"add_source_comments,omitempty"`
}

CSSBundleConfig configures css_bundle plugin for combining CSS files.

func NewCSSBundleConfig added in v0.7.0

func NewCSSBundleConfig() CSSBundleConfig

NewCSSBundleConfig creates a new CSSBundleConfig with default values.

func (*CSSBundleConfig) IsAddSourceComments added in v0.7.0

func (c *CSSBundleConfig) IsAddSourceComments() bool

IsAddSourceComments returns whether source comments should be added to bundles. Defaults to true if not explicitly set.

type CSSMinifyConfig added in v0.7.0

type CSSMinifyConfig struct {
	// Enabled controls whether CSS minification is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Exclude is a list of CSS file patterns to skip during minification.
	// Useful for files that should not be modified (e.g., already minified vendor CSS).
	// Example: ["variables.css", "vendor/*.css"]
	Exclude []string `json:"exclude" yaml:"exclude" toml:"exclude"`

	// PreserveComments is a list of comment patterns to preserve during minification.
	// Comments containing any of these strings will not be removed.
	// Example: ["/*! Copyright */", "/*! License */"]
	PreserveComments []string `json:"preserve_comments" yaml:"preserve_comments" toml:"preserve_comments"`
}

CSSMinifyConfig configures the css_minify plugin for minifying CSS files. CSS minification reduces file sizes by 15-30%, improving page load performance and Lighthouse scores.

func NewCSSMinifyConfig added in v0.7.0

func NewCSSMinifyConfig() CSSMinifyConfig

NewCSSMinifyConfig creates a new CSSMinifyConfig with default values.

type CSSPurgeConfig added in v0.7.0

type CSSPurgeConfig struct {
	// Enabled controls whether CSS purging is active (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Verbose enables detailed logging of purge operations (default: false)
	Verbose bool `json:"verbose" yaml:"verbose" toml:"verbose"`

	// Preserve is a list of glob patterns for CSS selectors to always keep.
	// These patterns match against class names and IDs.
	// Example: ["js-*", "htmx-*", "active", "hidden"]
	Preserve []string `json:"preserve" yaml:"preserve" toml:"preserve"`

	// PreserveAttributes is a list of attribute names to always preserve.
	// Selectors with these attributes (e.g., [data-theme], [data-palette]) will not be purged.
	// This is essential for runtime theming where attributes are set via JavaScript.
	// Example: ["data-theme", "data-palette"]
	PreserveAttributes []string `json:"preserve_attributes" yaml:"preserve_attributes" toml:"preserve_attributes"`

	// SkipFiles is a list of CSS file patterns to skip during purging.
	// Useful for third-party CSS that should not be modified.
	// Example: ["vendor/*", "normalize.css"]
	SkipFiles []string `json:"skip_files" yaml:"skip_files" toml:"skip_files"`

	// WarningThreshold is the minimum percentage of CSS removed before showing a warning.
	// If more than this percentage is removed, a warning is shown (might indicate overly aggressive purging).
	// Set to 0 to disable. Default: 0 (disabled)
	WarningThreshold int `json:"warning_threshold" yaml:"warning_threshold" toml:"warning_threshold"`
}

CSSPurgeConfig configures the css_purge plugin for removing unused CSS rules.

func NewCSSPurgeConfig added in v0.7.0

func NewCSSPurgeConfig() CSSPurgeConfig

NewCSSPurgeConfig creates a new CSSPurgeConfig with default values.

type CSVFenceConfig

type CSVFenceConfig struct {
	// Enabled controls whether CSV blocks are converted to tables (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// TableClass is the CSS class for generated tables (default: "csv-table")
	TableClass string `json:"table_class" yaml:"table_class" toml:"table_class"`

	// HasHeader indicates whether the first row is a header (default: true)
	HasHeader bool `json:"has_header" yaml:"has_header" toml:"has_header"`

	// Delimiter is the CSV field delimiter (default: ",")
	Delimiter string `json:"delimiter" yaml:"delimiter" toml:"delimiter"`
}

CSVFenceConfig configures the csv_fence plugin.

func NewCSVFenceConfig

func NewCSVFenceConfig() CSVFenceConfig

NewCSVFenceConfig creates a new CSVFenceConfig with default values.

type CardRouterConfig added in v0.7.0

type CardRouterConfig struct {
	// Mappings maps post template names to card template names.
	// User mappings are merged with defaults, allowing overrides.
	// Example: {"daily": "article", "meeting": "note"}
	Mappings map[string]string `json:"mappings,omitempty" yaml:"mappings,omitempty" toml:"mappings,omitempty"`
}

CardRouterConfig configures the card template routing for feeds. Maps post template types to card templates, merged with defaults.

func (*CardRouterConfig) GetCardTemplate added in v0.7.0

func (c *CardRouterConfig) GetCardTemplate(postTemplate string) string

GetCardTemplate returns the card template for a given post template. Returns the mapped card name, or "default" if not found.

func (*CardRouterConfig) MergedMappings added in v0.7.0

func (c *CardRouterConfig) MergedMappings() map[string]string

MergedMappings returns the user mappings merged with defaults. User mappings take precedence over defaults.

type ChartJSConfig added in v0.2.0

type ChartJSConfig struct {
	// Enabled controls whether Chart.js processing is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// CDNURL is the URL for the Chart.js library
	CDNURL string `json:"cdn_url" yaml:"cdn_url" toml:"cdn_url"`

	// ContainerClass is the CSS class for the chart container div (default: "chartjs-container")
	ContainerClass string `json:"container_class" yaml:"container_class" toml:"container_class"`
}

ChartJSConfig configures the chartjs plugin.

func NewChartJSConfig added in v0.2.0

func NewChartJSConfig() ChartJSConfig

NewChartJSConfig creates a new ChartJSConfig with default values.

type ChromiumRendererConfig added in v0.7.0

type ChromiumRendererConfig struct {
	// BrowserPath is the path to the Chrome/Chromium binary. If empty, auto-detects.
	BrowserPath string `json:"browser_path" yaml:"browser_path" toml:"browser_path"`

	// Timeout is the maximum time (in seconds) to wait for a diagram to render
	Timeout int `json:"timeout" yaml:"timeout" toml:"timeout"`

	// MaxConcurrent is the maximum number of concurrent diagram renders
	MaxConcurrent int `json:"max_concurrent" yaml:"max_concurrent" toml:"max_concurrent"`

	// NoSandbox disables the Chromium sandbox. Required in containers (Docker, Distrobox, etc.)
	NoSandbox bool `json:"no_sandbox" yaml:"no_sandbox" toml:"no_sandbox"`
}

ChromiumRendererConfig configures the Chromium-based renderer (mermaidcdp)

type ComponentsConfig added in v0.3.0

type ComponentsConfig struct {
	// Nav configures the navigation component
	Nav NavComponentConfig `json:"nav" yaml:"nav" toml:"nav"`

	// Footer configures the footer component
	Footer FooterComponentConfig `json:"footer" yaml:"footer" toml:"footer"`

	// DocSidebar configures the document sidebar (table of contents)
	DocSidebar DocSidebarConfig `json:"doc_sidebar" yaml:"doc_sidebar" toml:"doc_sidebar"`

	// FeedSidebar configures the feed sidebar (series/collection navigation)
	FeedSidebar FeedSidebarConfig `json:"feed_sidebar" yaml:"feed_sidebar" toml:"feed_sidebar"`

	// CardRouter configures the card template routing for feeds
	CardRouter CardRouterConfig `json:"card_router" yaml:"card_router" toml:"card_router"`

	// Share configures the per-post share component
	Share ShareComponentConfig `json:"share" yaml:"share" toml:"share"`
}

ComponentsConfig configures the layout components system. This enables configuration-driven control over common UI elements.

func NewComponentsConfig added in v0.3.0

func NewComponentsConfig() ComponentsConfig

NewComponentsConfig creates a new ComponentsConfig with default values.

func (*ComponentsConfig) IsDocSidebarEnabled added in v0.3.0

func (c *ComponentsConfig) IsDocSidebarEnabled() bool

IsDocSidebarEnabled returns whether the document sidebar is enabled.

func (*ComponentsConfig) IsFeedSidebarEnabled added in v0.3.0

func (c *ComponentsConfig) IsFeedSidebarEnabled() bool

IsFeedSidebarEnabled returns whether the feed sidebar is enabled.

func (*ComponentsConfig) IsFooterEnabled added in v0.3.0

func (c *ComponentsConfig) IsFooterEnabled() bool

IsFooterEnabled returns whether footer is enabled.

func (*ComponentsConfig) IsNavEnabled added in v0.3.0

func (c *ComponentsConfig) IsNavEnabled() bool

IsNavEnabled returns whether navigation is enabled.

type Config

type Config struct {
	// OutputDir is the directory where generated files are written (default: "output")
	OutputDir string `json:"output_dir" yaml:"output_dir" toml:"output_dir"`

	// URL is the base URL of the site
	URL string `json:"url" yaml:"url" toml:"url"`

	// Title is the site title
	Title string `json:"title" yaml:"title" toml:"title"`

	// Description is the site description
	Description string `json:"description" yaml:"description" toml:"description"`

	// Author is the site author
	Author string `json:"author" yaml:"author" toml:"author"`

	// License controls the footer attribution (string key or false)
	License LicenseValue `json:"license,omitempty" yaml:"license,omitempty" toml:"license,omitempty"`

	// AssetsDir is the directory containing static assets (default: "static")
	AssetsDir string `json:"assets_dir" yaml:"assets_dir" toml:"assets_dir"`

	// TemplatesDir is the directory containing templates (default: "templates")
	TemplatesDir string `json:"templates_dir" yaml:"templates_dir" toml:"templates_dir"`

	// Nav is the list of navigation links
	Nav []NavItem `json:"nav" yaml:"nav" toml:"nav"`

	// Footer configures the site footer
	Footer FooterConfig `json:"footer" yaml:"footer" toml:"footer"`

	// Hooks is the list of hooks to run (default: ["default"])
	Hooks []string `json:"hooks" yaml:"hooks" toml:"hooks"`

	// DisabledHooks is the list of hooks to disable
	DisabledHooks []string `json:"disabled_hooks" yaml:"disabled_hooks" toml:"disabled_hooks"`

	// GlobConfig configures file globbing behavior
	GlobConfig GlobConfig `json:"glob" yaml:"glob" toml:"glob"`

	// MarkdownConfig configures markdown processing
	MarkdownConfig MarkdownConfig `json:"markdown" yaml:"markdown" toml:"markdown"`

	// Feeds is the list of feed configurations
	Feeds []FeedConfig `json:"feeds" yaml:"feeds" toml:"feeds"`

	// FeedDefaults provides default values for feed configurations
	FeedDefaults FeedDefaults `json:"feed_defaults" yaml:"feed_defaults" toml:"feed_defaults"`

	// Concurrency is the number of concurrent workers (default: 0 = auto)
	Concurrency int `json:"concurrency" yaml:"concurrency" toml:"concurrency"`

	// Theme configures the site theme
	Theme ThemeConfig `json:"theme" yaml:"theme" toml:"theme"`

	// ThemeCalendar configures automatic seasonal theme switching based on date ranges
	ThemeCalendar ThemeCalendarConfig `json:"theme_calendar" yaml:"theme_calendar" toml:"theme_calendar"`

	// PostFormats configures output formats for individual posts
	PostFormats PostFormatsConfig `json:"post_formats" yaml:"post_formats" toml:"post_formats"`

	// WellKnown configures auto-generated .well-known endpoints
	WellKnown WellKnownConfig `json:"well_known" yaml:"well_known" toml:"well_known"`

	// SEO configures SEO metadata generation
	SEO SEOConfig `json:"seo" yaml:"seo" toml:"seo"`

	// IndieAuth configures IndieAuth link tags for identity and authentication
	IndieAuth IndieAuthConfig `json:"indieauth" yaml:"indieauth" toml:"indieauth"`

	// Webmention configures Webmention endpoint for receiving mentions
	Webmention WebmentionConfig `json:"webmention" yaml:"webmention" toml:"webmention"`

	// WebSub configures WebSub discovery links for feeds
	WebSub WebSubConfig `json:"websub" yaml:"websub" toml:"websub"`

	// Components configures layout components (nav, footer, sidebar)
	Components ComponentsConfig `json:"components" yaml:"components" toml:"components"`

	// Head configures elements added to the HTML <head> section
	Head HeadConfig `json:"head" yaml:"head" toml:"head"`

	// Search configures site-wide search functionality using Pagefind
	Search SearchConfig `json:"search" yaml:"search" toml:"search"`

	// Layout configures the layout system for page structure
	Layout LayoutConfig `json:"layout" yaml:"layout" toml:"layout"`

	// Sidebar configures the sidebar navigation component
	Sidebar SidebarConfig `json:"sidebar" yaml:"sidebar" toml:"sidebar"`

	// Toc configures the table of contents component
	Toc TocConfig `json:"toc" yaml:"toc" toml:"toc"`

	// Header configures the header component for layouts
	Header HeaderLayoutConfig `json:"header" yaml:"header" toml:"header"`

	// FooterLayout configures the footer component for layouts
	FooterLayout FooterLayoutConfig `json:"footer_layout" yaml:"footer_layout" toml:"footer_layout"`

	// ContentTemplates configures the content template system for the new command
	ContentTemplates ContentTemplatesConfig `json:"content_templates" yaml:"content_templates" toml:"content_templates"`

	// Blogroll configures the blogroll and RSS reader functionality
	Blogroll BlogrollConfig `json:"blogroll" yaml:"blogroll" toml:"blogroll"`

	// Mentions configures the @mentions resolution plugin
	Mentions MentionsConfig `json:"mentions" yaml:"mentions" toml:"mentions"`

	// ErrorPages configures custom error pages (404, etc.)
	ErrorPages ErrorPagesConfig `json:"error_pages" yaml:"error_pages" toml:"error_pages"`

	// ResourceHints configures automatic resource hints generation (preconnect, dns-prefetch, etc.)
	ResourceHints ResourceHintsConfig `json:"resource_hints" yaml:"resource_hints" toml:"resource_hints"`

	// Encryption configures content encryption for private posts
	Encryption EncryptionConfig `json:"encryption" yaml:"encryption" toml:"encryption"`

	// Shortcuts configures user-defined keyboard shortcuts
	Shortcuts ShortcutsConfig `json:"shortcuts" yaml:"shortcuts" toml:"shortcuts"`

	// Tags configures the tags listing page at /tags
	Tags TagsConfig `json:"tags" yaml:"tags" toml:"tags"`

	// Garden configures the garden view plugin for knowledge graph export and visualization
	Garden GardenConfig `json:"garden" yaml:"garden" toml:"garden"`

	// TagAggregator configures tag normalization and hierarchical expansion
	TagAggregator TagAggregatorConfig `json:"tag_aggregator" yaml:"tag_aggregator" toml:"tag_aggregator"`

	// Assets configures external CDN asset handling for self-hosting
	Assets AssetsConfig `json:"assets" yaml:"assets" toml:"assets"`

	// TemplatePresets defines named template preset configurations
	// Each preset specifies templates for all output formats
	TemplatePresets map[string]TemplatePreset `json:"template_presets,omitempty" yaml:"template_presets,omitempty" toml:"template_presets,omitempty"`

	// DefaultTemplates specifies default templates per output format
	// Keys: "html", "txt", "markdown", "og"
	// Values: template file names
	DefaultTemplates map[string]string `json:"default_templates,omitempty" yaml:"default_templates,omitempty" toml:"default_templates,omitempty"`

	// Authors configures multi-author support for the site
	Authors AuthorsConfig `json:"authors" yaml:"authors" toml:"authors"`

	// Extra holds arbitrary plugin configurations that aren't part of the core config.
	// Plugin-specific configs like [markata-go.image_zoom] are stored here.
	Extra map[string]any `json:"-" yaml:"-" toml:"-"`
}

Config represents the site configuration for markata-go.

func NewConfig

func NewConfig() *Config

NewConfig creates a new Config with default values.

func (*Config) ExternalCacheDirs added in v0.7.0

func (c *Config) ExternalCacheDirs() []string

ExternalCacheDirs returns the list of Tier 2 external plugin cache directories. These directories contain expensive-to-rebuild data (fetched RSS feeds, embed metadata, webmentions) and are only cleaned by --clean-all, not --clean. For plugins configured via the Extra map (embeds, webmentions), defaults are included when the plugin isn't explicitly configured, since the plugins still create these directories at runtime.

func (*Config) IsHookEnabled

func (c *Config) IsHookEnabled(name string) bool

IsHookEnabled checks if a hook is enabled (in Hooks and not in DisabledHooks).

func (*Config) LicenseOption added in v0.7.0

func (c *Config) LicenseOption() (LicenseOption, bool)

LicenseOption returns the configured license metadata when a valid key is present.

func (*Config) NeedsLicenseWarning added in v0.7.0

func (c *Config) NeedsLicenseWarning() bool

NeedsLicenseWarning reports whether the license reminder should be shown to users.

type ConfigValidationError

type ConfigValidationError struct {
	Field   string
	Value   interface{}
	Message string
}

ConfigValidationError indicates a configuration validation error.

func NewConfigValidationError

func NewConfigValidationError(field string, value interface{}, message string) *ConfigValidationError

NewConfigValidationError creates a new ConfigValidationError.

func (*ConfigValidationError) Error

func (e *ConfigValidationError) Error() string

type ContentTemplateConfig added in v0.5.0

type ContentTemplateConfig struct {
	// Name is the template identifier (e.g., "post", "page", "docs")
	Name string `json:"name" yaml:"name" toml:"name"`

	// Directory is the output directory for this content type
	Directory string `json:"directory" yaml:"directory" toml:"directory"`

	// Frontmatter contains default frontmatter fields for this template
	Frontmatter map[string]interface{} `json:"frontmatter,omitempty" yaml:"frontmatter,omitempty" toml:"frontmatter,omitempty"`

	// Body is the default body content (markdown) for this template
	Body string `json:"body,omitempty" yaml:"body,omitempty" toml:"body,omitempty"`
}

ContentTemplateConfig defines a single content template.

type ContentTemplatesConfig added in v0.5.0

type ContentTemplatesConfig struct {
	// Directory is where user-defined templates are stored (default: "content-templates")
	Directory string `json:"directory" yaml:"directory" toml:"directory"`

	// Placement maps template names to output directories
	Placement map[string]string `json:"placement" yaml:"placement" toml:"placement"`

	// Templates is a list of custom template configurations
	Templates []ContentTemplateConfig `json:"templates,omitempty" yaml:"templates,omitempty" toml:"templates,omitempty"`
}

ContentTemplatesConfig configures the content template system for the new command.

func NewContentTemplatesConfig added in v0.5.0

func NewContentTemplatesConfig() ContentTemplatesConfig

NewContentTemplatesConfig creates a new ContentTemplatesConfig with default values.

func (*ContentTemplatesConfig) GetPlacement added in v0.5.0

func (c *ContentTemplatesConfig) GetPlacement(templateName string) string

GetPlacement returns the output directory for a template name. Returns the template name itself if no explicit placement is configured.

type ContributionGraphConfig added in v0.6.0

type ContributionGraphConfig struct {
	// Enabled controls whether contribution graph processing is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// CDNURL is the URL for the Cal-Heatmap library
	CDNURL string `json:"cdn_url" yaml:"cdn_url" toml:"cdn_url"`

	// ContainerClass is the CSS class for the graph container div (default: "contribution-graph-container")
	ContainerClass string `json:"container_class" yaml:"container_class" toml:"container_class"`

	// Theme is the Cal-Heatmap color theme (default: "light")
	Theme string `json:"theme" yaml:"theme" toml:"theme"`
}

ContributionGraphConfig configures the contribution_graph plugin.

func NewContributionGraphConfig added in v0.6.0

func NewContributionGraphConfig() ContributionGraphConfig

NewContributionGraphConfig creates a new ContributionGraphConfig with default values.

type CriticalCSSConfig added in v0.7.0

type CriticalCSSConfig struct {
	// Enabled controls whether critical CSS optimization is active (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// ViewportWidth is reserved for future viewport-based critical CSS detection.
	// NOTE: Currently NOT implemented. The critical CSS extractor uses a selector-based
	// approach (see ExtraSelectors/ExcludeSelectors) rather than viewport simulation.
	// True viewport-based detection would require a headless browser.
	// This field is retained for configuration compatibility and future enhancement.
	// Default: 1300
	ViewportWidth int `json:"viewport_width,omitempty" yaml:"viewport_width,omitempty" toml:"viewport_width,omitempty"`

	// ViewportHeight is reserved for future viewport-based critical CSS detection.
	// NOTE: Currently NOT implemented. The critical CSS extractor uses a selector-based
	// approach (see ExtraSelectors/ExcludeSelectors) rather than viewport simulation.
	// True viewport-based detection would require a headless browser.
	// This field is retained for configuration compatibility and future enhancement.
	// Default: 900
	ViewportHeight int `json:"viewport_height,omitempty" yaml:"viewport_height,omitempty" toml:"viewport_height,omitempty"`

	// Minify controls whether to minify the critical CSS output (default: true)
	Minify *bool `json:"minify,omitempty" yaml:"minify,omitempty" toml:"minify,omitempty"`

	// PreloadNonCritical uses link rel="preload" for non-critical CSS (default: true)
	// This async loads the full stylesheet without blocking render
	PreloadNonCritical *bool `json:"preload_non_critical,omitempty" yaml:"preload_non_critical,omitempty" toml:"preload_non_critical,omitempty"`

	// ExtraSelectors is a list of additional CSS selectors to always include as critical
	// Useful for JavaScript-injected content that may appear above the fold
	ExtraSelectors []string `json:"extra_selectors,omitempty" yaml:"extra_selectors,omitempty" toml:"extra_selectors,omitempty"`

	// ExcludeSelectors is a list of CSS selectors to always exclude from critical CSS
	// Useful for content that should never be inlined (e.g., large animations)
	ExcludeSelectors []string `json:"exclude_selectors,omitempty" yaml:"exclude_selectors,omitempty" toml:"exclude_selectors,omitempty"`

	// InlineThreshold is the maximum size (in bytes) for the critical CSS before giving up inlining (default: 50000)
	// If critical CSS exceeds this threshold, the optimization is skipped for that page
	InlineThreshold int `json:"inline_threshold,omitempty" yaml:"inline_threshold,omitempty" toml:"inline_threshold,omitempty"`
}

CriticalCSSConfig configures the critical CSS extraction and inlining plugin. Critical CSS optimization inlines above-the-fold styles and async loads the rest, improving First Contentful Paint (FCP) by 200-800ms.

func NewCriticalCSSConfig added in v0.7.0

func NewCriticalCSSConfig() CriticalCSSConfig

NewCriticalCSSConfig creates a new CriticalCSSConfig with default values. Note: ViewportWidth and ViewportHeight are set for future compatibility but are not currently used by the selector-based critical CSS extractor.

func (*CriticalCSSConfig) IsEnabled added in v0.7.0

func (c *CriticalCSSConfig) IsEnabled() bool

IsEnabled returns whether critical CSS optimization is enabled. Defaults to false if not explicitly set.

func (*CriticalCSSConfig) IsMinify added in v0.7.0

func (c *CriticalCSSConfig) IsMinify() bool

IsMinify returns whether critical CSS minification is enabled. Defaults to true if not explicitly set.

func (*CriticalCSSConfig) IsPreloadNonCritical added in v0.7.0

func (c *CriticalCSSConfig) IsPreloadNonCritical() bool

IsPreloadNonCritical returns whether non-critical CSS should be preloaded. Defaults to true if not explicitly set.

type DocSidebarConfig added in v0.3.0

type DocSidebarConfig struct {
	// Enabled controls whether the TOC sidebar is displayed (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Position controls sidebar position: "left", "right" (default: "right")
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Width is the sidebar width (default: "250px")
	Width string `json:"width,omitempty" yaml:"width,omitempty" toml:"width,omitempty"`

	// MinDepth is the minimum heading level to include (default: 2)
	MinDepth int `json:"min_depth,omitempty" yaml:"min_depth,omitempty" toml:"min_depth,omitempty"`

	// MaxDepth is the maximum heading level to include (default: 4)
	MaxDepth int `json:"max_depth,omitempty" yaml:"max_depth,omitempty" toml:"max_depth,omitempty"`
}

DocSidebarConfig configures the document sidebar (table of contents).

type DocsLayoutConfig added in v0.4.0

type DocsLayoutConfig struct {
	// SidebarPosition controls sidebar placement: "left" or "right" (default: "left")
	SidebarPosition string `json:"sidebar_position,omitempty" yaml:"sidebar_position,omitempty" toml:"sidebar_position,omitempty"`

	// SidebarWidth is the width of the sidebar (default: "280px")
	SidebarWidth string `json:"sidebar_width,omitempty" yaml:"sidebar_width,omitempty" toml:"sidebar_width,omitempty"`

	// SidebarCollapsible allows the sidebar to be collapsed (default: true)
	SidebarCollapsible *bool `json:"sidebar_collapsible,omitempty" yaml:"sidebar_collapsible,omitempty" toml:"sidebar_collapsible,omitempty"`

	// SidebarDefaultOpen controls if sidebar is open by default on desktop (default: true)
	SidebarDefaultOpen *bool `json:"sidebar_default_open,omitempty" yaml:"sidebar_default_open,omitempty" toml:"sidebar_default_open,omitempty"`

	// TocPosition controls TOC placement: "left" or "right" (default: "right")
	TocPosition string `json:"toc_position,omitempty" yaml:"toc_position,omitempty" toml:"toc_position,omitempty"`

	// TocWidth is the width of the table of contents (default: "220px")
	TocWidth string `json:"toc_width,omitempty" yaml:"toc_width,omitempty" toml:"toc_width,omitempty"`

	// TocCollapsible allows the TOC to be collapsed (default: true)
	TocCollapsible *bool `json:"toc_collapsible,omitempty" yaml:"toc_collapsible,omitempty" toml:"toc_collapsible,omitempty"`

	// TocDefaultOpen controls if TOC is open by default on desktop (default: true)
	TocDefaultOpen *bool `json:"toc_default_open,omitempty" yaml:"toc_default_open,omitempty" toml:"toc_default_open,omitempty"`

	// ContentMaxWidth is the maximum width of the content area (default: "800px")
	ContentMaxWidth string `json:"content_max_width,omitempty" yaml:"content_max_width,omitempty" toml:"content_max_width,omitempty"`

	// HeaderStyle controls the header appearance: "full", "minimal", "transparent", "none" (default: "minimal")
	HeaderStyle string `json:"header_style,omitempty" yaml:"header_style,omitempty" toml:"header_style,omitempty"`

	// FooterStyle controls the footer appearance: "full", "minimal", "none" (default: "minimal")
	FooterStyle string `json:"footer_style,omitempty" yaml:"footer_style,omitempty" toml:"footer_style,omitempty"`
}

DocsLayoutConfig configures the documentation layout. This is a 3-panel layout with sidebar navigation, content, and table of contents.

func (*DocsLayoutConfig) IsSidebarCollapsible added in v0.4.0

func (d *DocsLayoutConfig) IsSidebarCollapsible() bool

IsSidebarCollapsible returns whether the sidebar can be collapsed.

func (*DocsLayoutConfig) IsSidebarDefaultOpen added in v0.4.0

func (d *DocsLayoutConfig) IsSidebarDefaultOpen() bool

IsSidebarDefaultOpen returns whether the sidebar is open by default.

func (*DocsLayoutConfig) IsTocCollapsible added in v0.4.0

func (d *DocsLayoutConfig) IsTocCollapsible() bool

IsTocCollapsible returns whether the TOC can be collapsed.

func (*DocsLayoutConfig) IsTocDefaultOpen added in v0.4.0

func (d *DocsLayoutConfig) IsTocDefaultOpen() bool

IsTocDefaultOpen returns whether the TOC is open by default.

type DomainHint added in v0.7.0

type DomainHint struct {
	// Domain is the external domain (e.g., "fonts.googleapis.com")
	Domain string `json:"domain" yaml:"domain" toml:"domain"`

	// HintTypes specifies which hint types to generate for this domain
	// Valid values: "preconnect", "dns-prefetch", "preload", "prefetch"
	HintTypes []string `json:"hint_types" yaml:"hint_types" toml:"hint_types"`

	// CrossOrigin specifies the crossorigin attribute value
	// Valid values: "", "anonymous", "use-credentials" (default: "")
	CrossOrigin string `json:"crossorigin,omitempty" yaml:"crossorigin,omitempty" toml:"crossorigin,omitempty"`

	// As specifies the "as" attribute for preload hints (e.g., "font", "script", "style")
	As string `json:"as,omitempty" yaml:"as,omitempty" toml:"as,omitempty"`
}

DomainHint represents a hint configuration for a specific domain.

type EmbedsConfig added in v0.5.0

type EmbedsConfig struct {
	// Enabled controls whether embed processing is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// InternalCardClass is the CSS class for internal embed cards (default: "embed-card")
	InternalCardClass string `json:"internal_card_class" yaml:"internal_card_class" toml:"internal_card_class"`

	// ExternalCardClass is the CSS class for external embed cards (default: "embed-card embed-card-external")
	ExternalCardClass string `json:"external_card_class" yaml:"external_card_class" toml:"external_card_class"`

	// FetchExternal enables fetching OG metadata for external embeds (default: true)
	FetchExternal bool `json:"fetch_external" yaml:"fetch_external" toml:"fetch_external"`

	// OEmbedEnabled enables oEmbed resolution for external embeds (default: true)
	OEmbedEnabled bool `json:"oembed_enabled" yaml:"oembed_enabled" toml:"oembed_enabled"`

	// ResolutionStrategy controls how external embeds are resolved (default: "oembed_first")
	ResolutionStrategy string `json:"resolution_strategy" yaml:"resolution_strategy" toml:"resolution_strategy"`

	// OEmbedProviders configures provider-specific overrides (default: empty)
	OEmbedProviders map[string]OEmbedProviderConfig `json:"providers" yaml:"providers" toml:"providers"`

	// OEmbedAutoDiscover enables auto-discovery via HTML link tags (default: false)
	OEmbedAutoDiscover bool `json:"oembed_auto_discover" yaml:"oembed_auto_discover" toml:"oembed_auto_discover"`

	// DefaultEmbedMode is the default mode for embeds when not specified (default: "card")
	// Options: rich, card, performance, hover
	DefaultEmbedMode string `json:"default_mode" yaml:"default_mode" toml:"default_mode"`

	// OEmbedProvidersURL is the URL to fetch oEmbed providers from (default: "https://oembed.com/providers.json")
	// Set to empty string to disable fetching from providers.json
	OEmbedProvidersURL string `json:"oembed_providers_url" yaml:"oembed_providers_url" toml:"oembed_providers_url"`

	// CacheDir is the directory for caching external embed metadata (default: ".cache/embeds")
	CacheDir string `json:"cache_dir" yaml:"cache_dir" toml:"cache_dir"`

	// Timeout is the HTTP request timeout in seconds for external fetches (default: 10)
	Timeout int `json:"timeout" yaml:"timeout" toml:"timeout"`

	// CacheTTL is the cache time-to-live in seconds for external metadata (default: 604800)
	CacheTTL int `json:"cache_ttl" yaml:"cache_ttl" toml:"cache_ttl"`

	// FallbackTitle is used when OG title cannot be fetched (default: "External Link")
	FallbackTitle string `json:"fallback_title" yaml:"fallback_title" toml:"fallback_title"`

	// ShowImage controls whether to display OG images in external embeds (default: true)
	ShowImage bool `json:"show_image" yaml:"show_image" toml:"show_image"`

	// AttachmentsPrefix is the URL prefix for attachment embeds (default: "/static/")
	// Used for Obsidian-style ![[image.jpg]] syntax
	AttachmentsPrefix string `json:"attachments_prefix" yaml:"attachments_prefix" toml:"attachments_prefix"`
}

EmbedsConfig configures the embeds plugin for embedding internal and external content.

func NewEmbedsConfig added in v0.5.0

func NewEmbedsConfig() EmbedsConfig

NewEmbedsConfig creates a new EmbedsConfig with default values.

type EncryptionConfig added in v0.7.0

type EncryptionConfig struct {
	// Enabled controls whether encryption processing is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// DefaultKey is the default encryption key name to use when a post doesn't specify one.
	// Maps to environment variable MARKATA_GO_ENCRYPTION_KEY_{DefaultKey}
	// Example: default_key: "blog" reads from MARKATA_GO_ENCRYPTION_KEY_BLOG
	// Default: "default" (reads from MARKATA_GO_ENCRYPTION_KEY_DEFAULT)
	DefaultKey string `json:"default_key,omitempty" yaml:"default_key,omitempty" toml:"default_key,omitempty"`

	// DecryptionHint is a hint shown to users about how to get the decryption password
	// Example: "Contact me on Twitter @user to get access"
	DecryptionHint string `json:"decryption_hint,omitempty" yaml:"decryption_hint,omitempty" toml:"decryption_hint,omitempty"`

	// PrivateTags maps tag names to encryption key names.
	// Any post with a matching tag is automatically treated as private and encrypted
	// with the specified key. Frontmatter secret_key overrides the tag-level key.
	// Example: {"diary": "personal", "draft-ideas": "default"}
	// This means any post tagged "diary" is encrypted with MARKATA_GO_ENCRYPTION_KEY_PERSONAL
	PrivateTags map[string]string `json:"private_tags,omitempty" yaml:"private_tags,omitempty" toml:"private_tags,omitempty"`
}

EncryptionConfig configures content encryption for private posts. When enabled and a post has private: true, the post content will be encrypted using AES-256-GCM and require client-side decryption.

Encryption is enabled by default with default_key="default". To use it, set MARKATA_GO_ENCRYPTION_KEY_DEFAULT in your environment or .env file.

func NewEncryptionConfig added in v0.7.0

func NewEncryptionConfig() EncryptionConfig

NewEncryptionConfig creates a new EncryptionConfig with default values. Encryption is enabled by default with default_key="default" so that any post with private: true is automatically encrypted. Users only need to set MARKATA_GO_ENCRYPTION_KEY_DEFAULT in their environment or .env file.

type EntityConfig added in v0.3.0

type EntityConfig struct {
	// Type is "Person" or "Organization" (default: "Organization")
	Type string `json:"type" yaml:"type" toml:"type"`

	// Name is the entity name
	Name string `json:"name" yaml:"name" toml:"name"`

	// URL is the entity's web page
	URL string `json:"url,omitempty" yaml:"url,omitempty" toml:"url,omitempty"`

	Logo string `json:"logo,omitempty" yaml:"logo,omitempty" toml:"logo,omitempty"`
}

EntityConfig represents a Schema.org Person or Organization entity.

type ErrorPagesConfig added in v0.7.0

type ErrorPagesConfig struct {
	// Enable404 enables the built-in 404 page (default: true)
	Enable404 *bool `json:"enable_404,omitempty" yaml:"enable_404,omitempty" toml:"enable_404,omitempty"`

	// Custom404Template is the path to a custom 404 template (default: "404.html")
	Custom404Template string `json:"custom_404_template,omitempty" yaml:"custom_404_template,omitempty" toml:"custom_404_template,omitempty"`

	// MaxSuggestions is the maximum number of similar posts to suggest (default: 5)
	MaxSuggestions int `json:"max_suggestions,omitempty" yaml:"max_suggestions,omitempty" toml:"max_suggestions,omitempty"`
}

ErrorPagesConfig configures custom error pages (404, etc.).

func NewErrorPagesConfig added in v0.7.0

func NewErrorPagesConfig() ErrorPagesConfig

NewErrorPagesConfig creates a new ErrorPagesConfig with default values.

func (*ErrorPagesConfig) Is404Enabled added in v0.7.0

func (e *ErrorPagesConfig) Is404Enabled() bool

Is404Enabled returns whether the 404 page is enabled. Defaults to true if not explicitly set.

type ExternalEntry added in v0.5.0

type ExternalEntry struct {
	// FeedURL is the source feed URL
	FeedURL string `json:"feed_url"`

	// FeedTitle is the source feed title
	FeedTitle string `json:"feed_title"`

	// ID is the unique identifier (GUID) for the entry
	ID string `json:"id"`

	// URL is the link to the full article
	URL string `json:"url"`

	// Title is the entry title
	Title string `json:"title"`

	// Description is a short summary or excerpt
	Description string `json:"description"`

	// Content is the full entry content (HTML)
	Content string `json:"content"`

	// Author is the entry author
	Author string `json:"author,omitempty"`

	// Published is the publication date
	Published *time.Time `json:"published,omitempty"`

	// Updated is the last update date
	Updated *time.Time `json:"updated,omitempty"`

	// Categories are the entry categories/tags
	Categories []string `json:"categories,omitempty"`

	// ImageURL is the entry's featured image
	ImageURL string `json:"image_url,omitempty"`

	// ReadingTime is estimated reading time in minutes
	ReadingTime int `json:"reading_time"`
}

ExternalEntry represents a single entry/item from an external feed.

type ExternalFeed added in v0.5.0

type ExternalFeed struct {
	// Config is the original configuration for this feed
	Config ExternalFeedConfig `json:"config"`

	// Title is the feed title (from config or fetched)
	Title string `json:"title"`

	// Description is the feed description
	Description string `json:"description"`

	// SiteURL is the main website URL
	SiteURL string `json:"site_url"`

	// FeedURL is the RSS/Atom feed URL
	FeedURL string `json:"feed_url"`

	// ImageURL is the feed's logo/icon (general image, may be article image)
	ImageURL string `json:"image_url"`

	// AvatarURL is the author/site representative image (person avatar)
	// Discovered via h-card u-photo, WebFinger rel=avatar, or .well-known/avatar
	AvatarURL string `json:"avatar_url,omitempty"`

	// AvatarSource indicates where the avatar was discovered from
	// Possible values: "config", "h-card", "webfinger", "well-known", "feed", "opengraph", "favicon"
	AvatarSource string `json:"avatar_source,omitempty"`

	// Category is the feed category
	Category string `json:"category"`

	// Tags are the feed tags
	Tags []string `json:"tags"`

	// LastFetched is when the feed was last fetched
	LastFetched *time.Time `json:"last_fetched,omitempty"`

	// LastUpdated is the feed's last build/update date
	LastUpdated *time.Time `json:"last_updated,omitempty"`

	// EntryCount is the number of entries in the feed
	EntryCount int `json:"entry_count"`

	// Entries are the feed entries/items
	Entries []*ExternalEntry `json:"entries"`

	// Error holds any error that occurred during fetching
	Error string `json:"error,omitempty"`
}

ExternalFeed represents a fetched and parsed external RSS/Atom feed.

type ExternalFeedConfig added in v0.5.0

type ExternalFeedConfig struct {
	// URL is the feed URL (required)
	URL string `json:"url" yaml:"url" toml:"url"`

	// Title is the human-readable feed title (optional, fetched if not set)
	Title string `json:"title" yaml:"title" toml:"title"`

	// Description is a short description of the feed
	Description string `json:"description" yaml:"description" toml:"description"`

	// Category groups feeds together (e.g., "technology", "design")
	Category string `json:"category" yaml:"category" toml:"category"`

	// Tags are additional labels for filtering
	Tags []string `json:"tags" yaml:"tags" toml:"tags"`

	// Active controls whether this feed is fetched (default: true)
	Active *bool `json:"active,omitempty" yaml:"active,omitempty" toml:"active,omitempty"`

	// SiteURL is the main website URL (fetched from feed if not set)
	SiteURL string `json:"site_url" yaml:"site_url" toml:"site_url"`

	// ImageURL is a logo or icon for the feed
	ImageURL string `json:"image_url" yaml:"image_url" toml:"image_url"`

	// Handle is an optional explicit handle for @mentions (e.g., "daverupert")
	// If not set, a handle is auto-generated from the domain
	Handle string `json:"handle" yaml:"handle" toml:"handle"`

	// Aliases are alternative names that resolve to the canonical Handle.
	// For example, aliases = ["dave", "david"] allows @dave or @david to
	// resolve to the same person as @daverupert. Case-insensitive.
	Aliases []string `json:"aliases,omitempty" yaml:"aliases,omitempty" toml:"aliases,omitempty"`

	// MaxEntries overrides the global max_entries_per_feed for this feed
	MaxEntries *int `json:"max_entries,omitempty" yaml:"max_entries,omitempty" toml:"max_entries,omitempty"`

	// Primary marks this as the canonical/primary feed for a person (default: true for entries without PrimaryPerson)
	// When a person has multiple feeds, mark the main one as primary=true
	Primary *bool `json:"primary,omitempty" yaml:"primary,omitempty" toml:"primary,omitempty"`

	// PrimaryPerson links this feed to a primary person's handle
	// Use this to associate secondary feeds (e.g., social accounts) with a primary person
	// Example: If "daverupert" is the primary handle, set primary_person="daverupert" on secondary feeds
	PrimaryPerson string `json:"primary_person" yaml:"primary_person" toml:"primary_person"`
}

ExternalFeedConfig represents a configured external RSS/Atom feed.

func (*ExternalFeedConfig) GetMaxEntries added in v0.5.0

func (f *ExternalFeedConfig) GetMaxEntries(globalDefault int) int

GetMaxEntries returns the per-feed max_entries if set, otherwise the global default.

func (*ExternalFeedConfig) IsActive added in v0.5.0

func (f *ExternalFeedConfig) IsActive() bool

IsActive returns whether the feed is active (defaults to true).

func (*ExternalFeedConfig) IsPrimary added in v0.5.0

func (f *ExternalFeedConfig) IsPrimary() bool

IsPrimary returns whether this is a primary feed (defaults to true if PrimaryPerson is not set).

type FeedConfig

type FeedConfig struct {
	// Slug is the URL-safe identifier for the feed
	Slug string `json:"slug" yaml:"slug" toml:"slug"`

	// Title is the feed title
	Title string `json:"title" yaml:"title" toml:"title"`

	// Description is the feed description
	Description string `json:"description" yaml:"description" toml:"description"`

	// Type is the feed type (blog, series, guide)
	Type FeedType `json:"type" yaml:"type" toml:"type"`

	// Filter is the filter expression for selecting posts
	Filter string `json:"filter" yaml:"filter" toml:"filter"`

	// Sort is the field to sort posts by
	Sort string `json:"sort" yaml:"sort" toml:"sort"`

	// Reverse indicates if the sort order should be reversed
	Reverse bool `json:"reverse" yaml:"reverse" toml:"reverse"`

	// ItemsPerPage is the number of items per page (default: 10)
	ItemsPerPage int `json:"items_per_page" yaml:"items_per_page" toml:"items_per_page"`

	// OrphanThreshold is the minimum number of items for a separate page (default: 3)
	OrphanThreshold int `json:"orphan_threshold" yaml:"orphan_threshold" toml:"orphan_threshold"`

	// PaginationType specifies the pagination strategy (manual, htmx, js)
	PaginationType PaginationType `json:"pagination_type" yaml:"pagination_type" toml:"pagination_type"`

	// Formats specifies which output formats to generate
	Formats FeedFormats `json:"formats" yaml:"formats" toml:"formats"`

	// Templates specifies custom templates for each format
	Templates FeedTemplates `json:"templates" yaml:"templates" toml:"templates"`

	// Sidebar enables auto-generation of sidebar navigation from this feed's posts
	Sidebar bool `json:"sidebar" yaml:"sidebar" toml:"sidebar"`

	// SidebarTitle overrides the feed title in sidebar navigation
	SidebarTitle string `json:"sidebar_title" yaml:"sidebar_title" toml:"sidebar_title"`

	// SidebarOrder controls the position in multi-feed sidebars (lower = first, default: 0)
	SidebarOrder int `json:"sidebar_order" yaml:"sidebar_order" toml:"sidebar_order"`

	// SidebarGroupBy groups posts by a frontmatter field in the sidebar (e.g., "category")
	SidebarGroupBy string `json:"sidebar_group_by" yaml:"sidebar_group_by" toml:"sidebar_group_by"`

	// IncludePrivate allows including private posts in this feed (default: false)
	IncludePrivate bool `json:"include_private,omitempty" yaml:"include_private,omitempty" toml:"include_private,omitempty"`

	// Posts holds the filtered posts at runtime (not serialized)
	Posts []*Post `json:"-" yaml:"-" toml:"-"`

	// Pages holds the paginated results at runtime (not serialized)
	Pages []FeedPage `json:"-" yaml:"-" toml:"-"`
}

FeedConfig represents a feed configuration.

func NewFeedConfig

func NewFeedConfig(defaults FeedDefaults) *FeedConfig

NewFeedConfig creates a new FeedConfig with default values from FeedDefaults.

func (*FeedConfig) ApplyDefaults

func (f *FeedConfig) ApplyDefaults(defaults FeedDefaults)

ApplyDefaults applies default values from FeedDefaults to a FeedConfig for any fields that are not explicitly set.

func (*FeedConfig) GetSidebarTitle added in v0.4.0

func (f *FeedConfig) GetSidebarTitle() string

GetSidebarTitle returns the effective title for sidebar navigation. Returns SidebarTitle if set, otherwise returns Title.

func (*FeedConfig) Paginate

func (f *FeedConfig) Paginate(baseURL string)

Paginate divides the Posts slice into pages based on ItemsPerPage and OrphanThreshold.

type FeedDefaults

type FeedDefaults struct {
	// ItemsPerPage is the default number of items per page
	ItemsPerPage int `json:"items_per_page" yaml:"items_per_page" toml:"items_per_page"`

	// OrphanThreshold is the default minimum number of items for a separate page
	OrphanThreshold int `json:"orphan_threshold" yaml:"orphan_threshold" toml:"orphan_threshold"`

	// PaginationType is the default pagination strategy
	PaginationType PaginationType `json:"pagination_type" yaml:"pagination_type" toml:"pagination_type"`

	// Formats specifies the default output formats
	Formats FeedFormats `json:"formats" yaml:"formats" toml:"formats"`

	// Templates specifies the default templates
	Templates FeedTemplates `json:"templates" yaml:"templates" toml:"templates"`

	// Syndication configures syndication feed behavior
	Syndication SyndicationConfig `json:"syndication" yaml:"syndication" toml:"syndication"`
}

FeedDefaults provides default values that feeds inherit.

func NewFeedDefaults

func NewFeedDefaults() FeedDefaults

NewFeedDefaults creates FeedDefaults with sensible default values.

type FeedFormats

type FeedFormats struct {
	// HTML generates an HTML page
	HTML bool `json:"html" yaml:"html" toml:"html"`

	// SimpleHTML generates a compact, dense list view of posts
	SimpleHTML bool `json:"simple_html" yaml:"simple_html" toml:"simple_html"`

	// RSS generates an RSS feed
	RSS bool `json:"rss" yaml:"rss" toml:"rss"`

	// Atom generates an Atom feed
	Atom bool `json:"atom" yaml:"atom" toml:"atom"`

	// JSON generates a JSON feed
	JSON bool `json:"json" yaml:"json" toml:"json"`

	// Markdown generates a Markdown file
	Markdown bool `json:"markdown" yaml:"markdown" toml:"markdown"`

	// Text generates a plain text file
	Text bool `json:"text" yaml:"text" toml:"text"`

	// Sitemap generates a sitemap XML file
	Sitemap bool `json:"sitemap" yaml:"sitemap" toml:"sitemap"`
}

FeedFormats specifies which output formats to generate for a feed.

func (FeedFormats) HasAnyEnabled

func (f FeedFormats) HasAnyEnabled() bool

HasAnyEnabled returns true if any output format is enabled.

type FeedPage

type FeedPage struct {
	// Number is the page number (1-indexed)
	Number int `json:"number" yaml:"number" toml:"number"`

	// Posts is the list of posts on this page
	Posts []*Post `json:"posts" yaml:"posts" toml:"posts"`

	// HasPrev indicates if there is a previous page
	HasPrev bool `json:"has_prev" yaml:"has_prev" toml:"has_prev"`

	// HasNext indicates if there is a next page
	HasNext bool `json:"has_next" yaml:"has_next" toml:"has_next"`

	// PrevURL is the URL of the previous page
	PrevURL string `json:"prev_url" yaml:"prev_url" toml:"prev_url"`

	// NextURL is the URL of the next page
	NextURL string `json:"next_url" yaml:"next_url" toml:"next_url"`

	// TotalPages is the total number of pages in the feed
	TotalPages int `json:"total_pages" yaml:"total_pages" toml:"total_pages"`

	// TotalItems is the total number of posts in the feed
	TotalItems int `json:"total_items" yaml:"total_items" toml:"total_items"`

	// ItemsPerPage is the number of posts per page
	ItemsPerPage int `json:"items_per_page" yaml:"items_per_page" toml:"items_per_page"`

	// PageURLs contains URLs for all pages (for numbered pagination)
	PageURLs []string `json:"page_urls" yaml:"page_urls" toml:"page_urls"`

	// PaginationType is the pagination strategy used
	PaginationType PaginationType `json:"pagination_type" yaml:"pagination_type" toml:"pagination_type"`
}

FeedPage represents a single page of paginated feed results.

type FeedSidebarConfig added in v0.3.0

type FeedSidebarConfig struct {
	// Enabled controls whether the feed sidebar is displayed (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Position controls sidebar position: "left", "right" (default: "left")
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Width is the sidebar width (default: "250px")
	Width string `json:"width,omitempty" yaml:"width,omitempty" toml:"width,omitempty"`

	// Title is the sidebar title (default: uses feed title or "In this series")
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Feeds is the list of feed slugs to show navigation for
	Feeds []string `json:"feeds,omitempty" yaml:"feeds,omitempty" toml:"feeds,omitempty"`
}

FeedSidebarConfig configures the feed sidebar (series/collection navigation).

type FeedTemplates

type FeedTemplates struct {
	// HTML is the template for HTML output
	HTML string `json:"html" yaml:"html" toml:"html"`

	// SimpleHTML is the template for simple HTML list output
	SimpleHTML string `json:"simple_html" yaml:"simple_html" toml:"simple_html"`

	// RSS is the template for RSS output
	RSS string `json:"rss" yaml:"rss" toml:"rss"`

	// Atom is the template for Atom output
	Atom string `json:"atom" yaml:"atom" toml:"atom"`

	// JSON is the template for JSON output
	JSON string `json:"json" yaml:"json" toml:"json"`

	// Card is the template for individual post cards
	Card string `json:"card" yaml:"card" toml:"card"`

	// Sitemap is the template for sitemap output
	Sitemap string `json:"sitemap" yaml:"sitemap" toml:"sitemap"`
}

FeedTemplates specifies custom templates for feed formats.

type FeedType added in v0.5.0

type FeedType string

FeedType represents the type of feed.

const (
	// FeedTypeBlog is a standard blog feed sorted by date.
	FeedTypeBlog FeedType = "blog"

	// FeedTypeSeries is a series of related posts.
	FeedTypeSeries FeedType = "series"

	// FeedTypeGuide is a guide series with ordered content and prerequisites.
	FeedTypeGuide FeedType = "guide"
)

type FilterExpressionError

type FilterExpressionError struct {
	Expression string
	Position   int
	Message    string
	Err        error
}

FilterExpressionError indicates an error in a filter expression.

func NewFilterExpressionError

func NewFilterExpressionError(expression, message string, err error) *FilterExpressionError

NewFilterExpressionError creates a new FilterExpressionError.

func (*FilterExpressionError) Error

func (e *FilterExpressionError) Error() string

func (*FilterExpressionError) Unwrap

func (e *FilterExpressionError) Unwrap() error

type FontConfig added in v0.6.0

type FontConfig struct {
	// Family is the primary font family for body text (default: "system-ui, -apple-system, sans-serif")
	Family string `json:"family,omitempty" yaml:"family,omitempty" toml:"family,omitempty"`

	// HeadingFamily is the font family for headings (default: inherits from Family)
	HeadingFamily string `json:"heading_family,omitempty" yaml:"heading_family,omitempty" toml:"heading_family,omitempty"`

	// CodeFamily is the font family for code blocks and inline code (default: "ui-monospace, monospace")
	CodeFamily string `json:"code_family,omitempty" yaml:"code_family,omitempty" toml:"code_family,omitempty"`

	// Size is the base font size (default: "16px")
	Size string `json:"size,omitempty" yaml:"size,omitempty" toml:"size,omitempty"`

	// LineHeight is the base line height (default: "1.6")
	LineHeight string `json:"line_height,omitempty" yaml:"line_height,omitempty" toml:"line_height,omitempty"`

	// GoogleFonts is a list of Google Fonts to load (e.g., ["Inter", "Fira Code"])
	GoogleFonts []string `json:"google_fonts,omitempty" yaml:"google_fonts,omitempty" toml:"google_fonts,omitempty"`

	// CustomURLs is a list of custom font CSS URLs to load
	CustomURLs []string `json:"custom_urls,omitempty" yaml:"custom_urls,omitempty" toml:"custom_urls,omitempty"`
}

FontConfig configures typography settings for the site.

func NewFontConfig added in v0.6.0

func NewFontConfig() FontConfig

NewFontConfig creates a new FontConfig with default values.

func (*FontConfig) GetGoogleFontsURL added in v0.6.0

func (f *FontConfig) GetGoogleFontsURL() string

GetGoogleFontsURL returns the Google Fonts CSS URL for the configured fonts. Returns empty string if no Google Fonts are configured.

func (*FontConfig) GetHeadingFamily added in v0.6.0

func (f *FontConfig) GetHeadingFamily() string

GetHeadingFamily returns the heading font family, falling back to Family if not set.

type FooterComponentConfig added in v0.3.0

type FooterComponentConfig struct {
	// Enabled controls whether footer is displayed (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Text is the footer text (supports template variables)
	Text string `json:"text,omitempty" yaml:"text,omitempty" toml:"text,omitempty"`

	// ShowCopyright shows the copyright line (default: true)
	ShowCopyright *bool `json:"show_copyright,omitempty" yaml:"show_copyright,omitempty" toml:"show_copyright,omitempty"`

	// ShowBuiltWith shows the "built with markata-go" text (default: true)
	ShowBuiltWith *bool `json:"show_built_with,omitempty" yaml:"show_built_with,omitempty" toml:"show_built_with,omitempty"`

	// Links are additional footer links
	Links []NavItem `json:"links,omitempty" yaml:"links,omitempty" toml:"links,omitempty"`
}

FooterComponentConfig configures the footer component.

type FooterConfig added in v0.3.0

type FooterConfig struct {
	// Text is the footer text (supports template variables like {{ year }})
	Text string `json:"text,omitempty" yaml:"text,omitempty" toml:"text,omitempty"`

	// ShowCopyright shows the copyright line (default: true)
	ShowCopyright *bool `json:"show_copyright,omitempty" yaml:"show_copyright,omitempty" toml:"show_copyright,omitempty"`
}

FooterConfig configures the site footer.

type FooterLayoutConfig added in v0.4.0

type FooterLayoutConfig struct {
	// Style controls the footer appearance: "full", "minimal", "none" (default: "full")
	Style string `json:"style,omitempty" yaml:"style,omitempty" toml:"style,omitempty"`

	// Sticky makes the footer stick to the bottom (default: false)
	Sticky *bool `json:"sticky,omitempty" yaml:"sticky,omitempty" toml:"sticky,omitempty"`

	// ShowCopyright displays the copyright notice (default: true)
	ShowCopyright *bool `json:"show_copyright,omitempty" yaml:"show_copyright,omitempty" toml:"show_copyright,omitempty"`

	// CopyrightText is the copyright text (default: auto-generated)
	CopyrightText string `json:"copyright_text,omitempty" yaml:"copyright_text,omitempty" toml:"copyright_text,omitempty"`

	// ShowSocialLinks displays social media links (default: true)
	ShowSocialLinks *bool `json:"show_social_links,omitempty" yaml:"show_social_links,omitempty" toml:"show_social_links,omitempty"`

	// ShowNavLinks displays navigation links in footer (default: true)
	ShowNavLinks *bool `json:"show_nav_links,omitempty" yaml:"show_nav_links,omitempty" toml:"show_nav_links,omitempty"`
}

FooterLayoutConfig configures the footer component for layouts.

func NewFooterLayoutConfig added in v0.4.0

func NewFooterLayoutConfig() FooterLayoutConfig

NewFooterLayoutConfig creates a new FooterLayoutConfig with default values.

func (*FooterLayoutConfig) IsShowCopyright added in v0.4.0

func (f *FooterLayoutConfig) IsShowCopyright() bool

IsShowCopyright returns whether to show the copyright.

func (f *FooterLayoutConfig) IsShowNavLinks() bool

IsShowNavLinks returns whether to show nav links in footer.

func (f *FooterLayoutConfig) IsShowSocialLinks() bool

IsShowSocialLinks returns whether to show social links.

func (*FooterLayoutConfig) IsSticky added in v0.4.0

func (f *FooterLayoutConfig) IsSticky() bool

IsSticky returns whether the footer should be sticky.

type FrontmatterParseError

type FrontmatterParseError struct {
	Path    string
	Line    int
	Message string
	Err     error
}

FrontmatterParseError indicates an error parsing frontmatter from a post.

func NewFrontmatterParseError

func NewFrontmatterParseError(path, message string, err error) *FrontmatterParseError

NewFrontmatterParseError creates a new FrontmatterParseError.

func (*FrontmatterParseError) Error

func (e *FrontmatterParseError) Error() string

func (*FrontmatterParseError) Unwrap

func (e *FrontmatterParseError) Unwrap() error

type GardenConfig added in v0.7.0

type GardenConfig struct {
	// Enabled controls whether the garden view is generated (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Path is the output path prefix for garden files (default: "garden")
	Path string `json:"path,omitempty" yaml:"path,omitempty" toml:"path,omitempty"`

	// ExportJSON enables emitting graph.json with the relationship graph (default: true)
	ExportJSON *bool `json:"export_json,omitempty" yaml:"export_json,omitempty" toml:"export_json,omitempty"`

	// RenderPage enables generating garden/index.html (default: true)
	RenderPage *bool `json:"render_page,omitempty" yaml:"render_page,omitempty" toml:"render_page,omitempty"`

	// IncludeTags includes tag nodes in the graph (default: true)
	IncludeTags *bool `json:"include_tags,omitempty" yaml:"include_tags,omitempty" toml:"include_tags,omitempty"`

	// IncludePosts includes post nodes in the graph (default: true)
	IncludePosts *bool `json:"include_posts,omitempty" yaml:"include_posts,omitempty" toml:"include_posts,omitempty"`

	// MaxNodes is the maximum number of nodes in the graph (default: 2000)
	// When exceeded, least-used tags are removed first
	MaxNodes int `json:"max_nodes,omitempty" yaml:"max_nodes,omitempty" toml:"max_nodes,omitempty"`

	// ExcludeTags is a list of tag names to exclude from the graph
	ExcludeTags []string `json:"exclude_tags,omitempty" yaml:"exclude_tags,omitempty" toml:"exclude_tags,omitempty"`

	// Template is the template file to use for the garden page (default: "garden.html")
	Template string `json:"template,omitempty" yaml:"template,omitempty" toml:"template,omitempty"`

	// Title is the title for the garden page (default: "Garden")
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Description is the description for the garden page
	Description string `json:"description,omitempty" yaml:"description,omitempty" toml:"description,omitempty"`
}

GardenConfig configures the garden view plugin for knowledge graph export and visualization. The garden provides a way to explore content by relationships (tags, links) rather than chronology. It exports a graph.json file and optionally renders an interactive garden page.

func NewGardenConfig added in v0.7.0

func NewGardenConfig() GardenConfig

NewGardenConfig creates a new GardenConfig with default values.

func (*GardenConfig) GetMaxNodes added in v0.7.0

func (g *GardenConfig) GetMaxNodes() int

GetMaxNodes returns the max nodes, with default if not set.

func (*GardenConfig) GetPath added in v0.7.0

func (g *GardenConfig) GetPath() string

GetPath returns the output path, with default if not set.

func (*GardenConfig) GetTemplate added in v0.7.0

func (g *GardenConfig) GetTemplate() string

GetTemplate returns the template name, with default if not set.

func (*GardenConfig) IsEnabled added in v0.7.0

func (g *GardenConfig) IsEnabled() bool

IsEnabled returns whether the garden view is enabled. Defaults to true if not explicitly set.

func (*GardenConfig) IsExportJSON added in v0.7.0

func (g *GardenConfig) IsExportJSON() bool

IsExportJSON returns whether graph.json export is enabled. Defaults to true if not explicitly set.

func (*GardenConfig) IsIncludePosts added in v0.7.0

func (g *GardenConfig) IsIncludePosts() bool

IsIncludePosts returns whether post nodes should be included in the graph. Defaults to true if not explicitly set.

func (*GardenConfig) IsIncludeTags added in v0.7.0

func (g *GardenConfig) IsIncludeTags() bool

IsIncludeTags returns whether tag nodes should be included in the graph. Defaults to true if not explicitly set.

func (*GardenConfig) IsRenderPage added in v0.7.0

func (g *GardenConfig) IsRenderPage() bool

IsRenderPage returns whether the garden HTML page should be rendered. Defaults to true if not explicitly set.

func (*GardenConfig) IsTagExcluded added in v0.7.0

func (g *GardenConfig) IsTagExcluded(tag string) bool

IsTagExcluded returns whether a tag is in the exclude list.

type GlobConfig

type GlobConfig struct {
	// Patterns is the list of glob patterns to match source files
	Patterns []string `json:"patterns" yaml:"patterns" toml:"patterns"`

	// UseGitignore determines whether to respect .gitignore files
	UseGitignore bool `json:"use_gitignore" yaml:"use_gitignore" toml:"use_gitignore"`
}

GlobConfig configures file globbing behavior.

type HeadConfig added in v0.3.0

type HeadConfig struct {
	// Text is raw HTML/text to include in the head (use with caution)
	Text string `json:"text,omitempty" yaml:"text,omitempty" toml:"text,omitempty"`

	// Meta is a list of meta tags to include
	Meta []MetaTag `json:"meta,omitempty" yaml:"meta,omitempty" toml:"meta,omitempty"`

	// Link is a list of link tags to include
	Link []LinkTag `json:"link,omitempty" yaml:"link,omitempty" toml:"link,omitempty"`

	// Script is a list of script tags to include
	Script []ScriptTag `json:"script,omitempty" yaml:"script,omitempty" toml:"script,omitempty"`

	// AlternateFeeds configures which feeds get <link rel="alternate"> tags
	// If empty, defaults to RSS and Atom feeds
	AlternateFeeds []AlternateFeed `json:"alternate_feeds,omitempty" yaml:"alternate_feeds,omitempty" toml:"alternate_feeds,omitempty"`
}

HeadConfig configures elements added to the HTML <head> section.

type HeaderLayoutConfig added in v0.4.0

type HeaderLayoutConfig struct {
	// Style controls the header appearance: "full", "minimal", "transparent", "none" (default: "full")
	Style string `json:"style,omitempty" yaml:"style,omitempty" toml:"style,omitempty"`

	// Sticky makes the header stick to the top when scrolling (default: true)
	Sticky *bool `json:"sticky,omitempty" yaml:"sticky,omitempty" toml:"sticky,omitempty"`

	ShowLogo *bool `json:"show_logo,omitempty" yaml:"show_logo,omitempty" toml:"show_logo,omitempty"`

	// ShowTitle displays the site title (default: true)
	ShowTitle *bool `json:"show_title,omitempty" yaml:"show_title,omitempty" toml:"show_title,omitempty"`

	// ShowNav displays the navigation links (default: true)
	ShowNav *bool `json:"show_nav,omitempty" yaml:"show_nav,omitempty" toml:"show_nav,omitempty"`

	// ShowSearch displays the search box (default: true)
	ShowSearch *bool `json:"show_search,omitempty" yaml:"show_search,omitempty" toml:"show_search,omitempty"`

	// ShowThemeToggle displays the theme toggle button (default: true)
	ShowThemeToggle *bool `json:"show_theme_toggle,omitempty" yaml:"show_theme_toggle,omitempty" toml:"show_theme_toggle,omitempty"`
}

HeaderLayoutConfig configures the header component for layouts.

func NewHeaderLayoutConfig added in v0.4.0

func NewHeaderLayoutConfig() HeaderLayoutConfig

NewHeaderLayoutConfig creates a new HeaderLayoutConfig with default values.

func (h *HeaderLayoutConfig) IsShowLogo() bool

IsShowLogo returns whether to show the logo.

func (*HeaderLayoutConfig) IsShowNav added in v0.4.0

func (h *HeaderLayoutConfig) IsShowNav() bool

IsShowNav returns whether to show navigation.

func (*HeaderLayoutConfig) IsShowSearch added in v0.4.0

func (h *HeaderLayoutConfig) IsShowSearch() bool

IsShowSearch returns whether to show the search box.

func (*HeaderLayoutConfig) IsShowThemeToggle added in v0.4.0

func (h *HeaderLayoutConfig) IsShowThemeToggle() bool

IsShowThemeToggle returns whether to show the theme toggle.

func (*HeaderLayoutConfig) IsShowTitle added in v0.4.0

func (h *HeaderLayoutConfig) IsShowTitle() bool

IsShowTitle returns whether to show the title.

func (*HeaderLayoutConfig) IsSticky added in v0.4.0

func (h *HeaderLayoutConfig) IsSticky() bool

IsSticky returns whether the header should be sticky.

type HighlightConfig

type HighlightConfig struct {
	// Enabled controls whether syntax highlighting is active (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Theme is the Chroma theme to use for syntax highlighting.
	// If empty, the theme is automatically derived from the site's color palette.
	// See https://xyproto.github.io/splash/docs/ for available themes.
	Theme string `json:"theme,omitempty" yaml:"theme,omitempty" toml:"theme,omitempty"`

	// LineNumbers enables line numbers in code blocks (default: false)
	LineNumbers bool `json:"line_numbers" yaml:"line_numbers" toml:"line_numbers"`
}

HighlightConfig configures syntax highlighting for code blocks.

func NewHighlightConfig

func NewHighlightConfig() HighlightConfig

NewHighlightConfig creates a new HighlightConfig with default values.

func (*HighlightConfig) IsEnabled

func (h *HighlightConfig) IsEnabled() bool

IsEnabled returns whether syntax highlighting is enabled. Defaults to true if not explicitly set.

type ImageObject added in v0.3.0

type ImageObject struct {
	Type string `json:"@type"`
	URL  string `json:"url"`
}

ImageObject represents a Schema.org ImageObject.

type ImageZoomConfig added in v0.6.0

type ImageZoomConfig struct {
	// Enabled controls whether image zoom is active (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Library is the lightbox library to use (default: "glightbox")
	// Supported: "glightbox"
	Library string `json:"library" yaml:"library" toml:"library"`

	// Selector is the CSS selector for images to make zoomable (default: ".glightbox")
	Selector string `json:"selector" yaml:"selector" toml:"selector"`

	// CDN uses CDN for library files instead of local (default: true)
	CDN bool `json:"cdn" yaml:"cdn" toml:"cdn"`

	// AutoAllImages enables zoom on all images without explicit marking (default: false)
	AutoAllImages bool `json:"auto_all_images" yaml:"auto_all_images" toml:"auto_all_images"`

	// OpenEffect is the effect when opening the lightbox (default: "zoom")
	// Options: "zoom", "fade", "none"
	OpenEffect string `json:"open_effect" yaml:"open_effect" toml:"open_effect"`

	// CloseEffect is the effect when closing the lightbox (default: "zoom")
	// Options: "zoom", "fade", "none"
	CloseEffect string `json:"close_effect" yaml:"close_effect" toml:"close_effect"`

	// SlideEffect is the effect when sliding between images (default: "slide")
	// Options: "slide", "fade", "zoom", "none"
	SlideEffect string `json:"slide_effect" yaml:"slide_effect" toml:"slide_effect"`

	// TouchNavigation enables touch/swipe navigation (default: true)
	TouchNavigation bool `json:"touch_navigation" yaml:"touch_navigation" toml:"touch_navigation"`

	// Loop enables looping through images in a gallery (default: false)
	Loop bool `json:"loop" yaml:"loop" toml:"loop"`

	// Draggable enables dragging images to navigate (default: true)
	Draggable bool `json:"draggable" yaml:"draggable" toml:"draggable"`
}

ImageZoomConfig configures the image_zoom plugin for lightbox functionality.

func NewImageZoomConfig added in v0.6.0

func NewImageZoomConfig() ImageZoomConfig

NewImageZoomConfig creates a new ImageZoomConfig with default values.

type IndieAuthConfig added in v0.3.0

type IndieAuthConfig struct {
	// Enabled controls whether IndieAuth link tags are included (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// AuthorizationEndpoint is the URL of your authorization endpoint
	// Example: "https://indieauth.com/auth"
	AuthorizationEndpoint string `json:"authorization_endpoint" yaml:"authorization_endpoint" toml:"authorization_endpoint"`

	// TokenEndpoint is the URL of your token endpoint
	// Example: "https://tokens.indieauth.com/token"
	TokenEndpoint string `json:"token_endpoint" yaml:"token_endpoint" toml:"token_endpoint"`

	// MeURL is your profile URL for rel="me" links (optional)
	// This links your site to other profiles (GitHub, Twitter, etc.)
	MeURL string `json:"me_url" yaml:"me_url" toml:"me_url"`
}

IndieAuthConfig configures IndieAuth link tags for identity and authentication. IndieAuth is a decentralized authentication protocol built on OAuth 2.0. See https://indieauth.spec.indieweb.org/ for the specification.

func NewIndieAuthConfig added in v0.3.0

func NewIndieAuthConfig() IndieAuthConfig

NewIndieAuthConfig creates a new IndieAuthConfig with default values.

type JSMinifyConfig added in v0.7.0

type JSMinifyConfig struct {
	// Enabled controls whether JS minification is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Exclude is a list of JS file patterns to skip during minification.
	// Useful for files that should not be modified (e.g., vendor scripts).
	// Files ending in .min.js are always excluded automatically.
	// Example: ["pagefind-ui.js", "vendor/*.js"]
	Exclude []string `json:"exclude" yaml:"exclude" toml:"exclude"`
}

JSMinifyConfig configures the js_minify plugin for minifying JavaScript files. JS minification reduces file sizes by 40-60%, improving page load performance and Lighthouse scores. Already-minified files (*.min.js) are automatically skipped.

func NewJSMinifyConfig added in v0.7.0

func NewJSMinifyConfig() JSMinifyConfig

NewJSMinifyConfig creates a new JSMinifyConfig with default values.

type LandingLayoutConfig added in v0.4.0

type LandingLayoutConfig struct {
	// ContentMaxWidth is the maximum width of the content area (default: "100%")
	ContentMaxWidth string `json:"content_max_width,omitempty" yaml:"content_max_width,omitempty" toml:"content_max_width,omitempty"`

	// HeaderStyle controls the header appearance: "full", "minimal", "transparent", "none" (default: "transparent")
	HeaderStyle string `json:"header_style,omitempty" yaml:"header_style,omitempty" toml:"header_style,omitempty"`

	// HeaderSticky makes the header stick when scrolling (default: true)
	HeaderSticky *bool `json:"header_sticky,omitempty" yaml:"header_sticky,omitempty" toml:"header_sticky,omitempty"`

	// FooterStyle controls the footer appearance: "full", "minimal", "none" (default: "full")
	FooterStyle string `json:"footer_style,omitempty" yaml:"footer_style,omitempty" toml:"footer_style,omitempty"`

	// HeroEnabled enables the hero section (default: true)
	HeroEnabled *bool `json:"hero_enabled,omitempty" yaml:"hero_enabled,omitempty" toml:"hero_enabled,omitempty"`
}

LandingLayoutConfig configures the landing page layout. This is a full-width layout for marketing pages and home pages.

func (*LandingLayoutConfig) IsHeaderSticky added in v0.4.0

func (l *LandingLayoutConfig) IsHeaderSticky() bool

IsHeaderSticky returns whether the header should be sticky.

func (*LandingLayoutConfig) IsHeroEnabled added in v0.4.0

func (l *LandingLayoutConfig) IsHeroEnabled() bool

IsHeroEnabled returns whether the hero section is enabled.

type LayoutConfig added in v0.4.0

type LayoutConfig struct {
	// Name is the default layout preset name (default: "blog")
	// Options: "docs", "blog", "landing", "bare"
	Name string `json:"name,omitempty" yaml:"name,omitempty" toml:"name,omitempty"`

	// Paths maps URL path prefixes to layout names for automatic layout selection.
	// Example: {"/docs/": "docs", "/blog/": "blog", "/about/": "landing"}
	Paths map[string]string `json:"paths,omitempty" yaml:"paths,omitempty" toml:"paths,omitempty"`

	// Feeds maps feed slugs to layout names for automatic layout selection.
	// Example: {"docs": "docs", "blog": "blog"}
	Feeds map[string]string `json:"feeds,omitempty" yaml:"feeds,omitempty" toml:"feeds,omitempty"`

	// Docs configures the documentation layout
	Docs DocsLayoutConfig `json:"docs,omitempty" yaml:"docs,omitempty" toml:"docs,omitempty"`

	// Blog configures the blog layout
	Blog BlogLayoutConfig `json:"blog,omitempty" yaml:"blog,omitempty" toml:"blog,omitempty"`

	// Landing configures the landing page layout
	Landing LandingLayoutConfig `json:"landing,omitempty" yaml:"landing,omitempty" toml:"landing,omitempty"`

	// Bare configures the bare layout (content only)
	Bare BareLayoutConfig `json:"bare,omitempty" yaml:"bare,omitempty" toml:"bare,omitempty"`

	// Defaults provides global layout defaults
	Defaults LayoutDefaults `json:"defaults,omitempty" yaml:"defaults,omitempty" toml:"defaults,omitempty"`
}

LayoutConfig configures the site layout system. Layouts control the overall page structure including sidebars, TOC, header, and footer.

func NewLayoutConfig added in v0.4.0

func NewLayoutConfig() LayoutConfig

NewLayoutConfig creates a new LayoutConfig with default values.

func (*LayoutConfig) ResolveLayout added in v0.4.0

func (l *LayoutConfig) ResolveLayout(postPath, feedSlug string) string

ResolveLayout determines the appropriate layout for a post based on its path and feed. Priority: path-based > feed-based > global default Returns the layout name (e.g., "docs", "blog", "landing", "bare") or empty string if no match.

type LayoutDefaults added in v0.4.0

type LayoutDefaults struct {
	// ContentMaxWidth is the maximum width of the content area (default: "800px")
	ContentMaxWidth string `json:"content_max_width,omitempty" yaml:"content_max_width,omitempty" toml:"content_max_width,omitempty"`

	// HeaderSticky makes the header stick to the top when scrolling (default: true)
	HeaderSticky *bool `json:"header_sticky,omitempty" yaml:"header_sticky,omitempty" toml:"header_sticky,omitempty"`

	// FooterSticky makes the footer stick to the bottom (default: false)
	FooterSticky *bool `json:"footer_sticky,omitempty" yaml:"footer_sticky,omitempty" toml:"footer_sticky,omitempty"`
}

LayoutDefaults provides global layout defaults.

func (*LayoutDefaults) IsFooterSticky added in v0.4.0

func (d *LayoutDefaults) IsFooterSticky() bool

IsFooterSticky returns whether the footer should be sticky.

func (*LayoutDefaults) IsHeaderSticky added in v0.4.0

func (d *LayoutDefaults) IsHeaderSticky() bool

IsHeaderSticky returns whether the header should be sticky.

type LicenseOption added in v0.7.0

type LicenseOption struct {
	Key         string
	Name        string
	URL         string
	Description string
	Recommended bool
}

LicenseOption describes a supported license key and the human-readable attribution that is rendered in the footer.

func GetLicenseOption added in v0.7.0

func GetLicenseOption(key string) (LicenseOption, bool)

GetLicenseOption looks up the license option for a normalized key.

type LicenseValue added in v0.7.0

type LicenseValue struct {
	Raw interface{}
}

LicenseValue tracks the raw value provided for the `license` key. It can be either a string, or the boolean false when the setting is disabled.

func (LicenseValue) HasValue added in v0.7.0

func (l LicenseValue) HasValue() bool

HasValue reports whether any explicit license value was provided.

func (LicenseValue) IsDisabled added in v0.7.0

func (l LicenseValue) IsDisabled() bool

IsDisabled returns true when the value was the boolean false starter.

func (LicenseValue) Key added in v0.7.0

func (l LicenseValue) Key() (string, bool)

Key returns the normalized string key when the value is a string.

func (LicenseValue) MarshalJSON added in v0.7.0

func (l LicenseValue) MarshalJSON() ([]byte, error)

MarshalJSON writes the raw value so serialized configs match the input.

func (LicenseValue) MarshalTOML added in v0.7.0

func (l LicenseValue) MarshalTOML() (interface{}, error)

MarshalTOML implements the BurntSushi toml.Marshaler interface.

func (LicenseValue) MarshalYAML added in v0.7.0

func (l LicenseValue) MarshalYAML() (interface{}, error)

MarshalYAML implements yaml.Marshaler.

type Link struct {
	// SourceURL is the absolute URL of the source post
	SourceURL string `json:"source_url" yaml:"source_url" toml:"source_url"`

	// SourcePost is a reference to the source post object
	SourcePost *Post `json:"-" yaml:"-" toml:"-"`

	// TargetPost is a reference to the target post (nil if external)
	TargetPost *Post `json:"-" yaml:"-" toml:"-"`

	// RawTarget is the original href value as found in the HTML
	RawTarget string `json:"raw_target" yaml:"raw_target" toml:"raw_target"`

	// TargetURL is the resolved absolute URL
	TargetURL string `json:"target_url" yaml:"target_url" toml:"target_url"`

	// TargetDomain is the domain extracted from target_url
	TargetDomain string `json:"target_domain" yaml:"target_domain" toml:"target_domain"`

	// IsInternal is true if the link points to the same site
	IsInternal bool `json:"is_internal" yaml:"is_internal" toml:"is_internal"`

	// IsSelf is true if the link points to the same post
	IsSelf bool `json:"is_self" yaml:"is_self" toml:"is_self"`

	// SourceText is the cleaned link text from the source anchor
	SourceText string `json:"source_text" yaml:"source_text" toml:"source_text"`

	// TargetText is the cleaned link text from the target (if available)
	TargetText string `json:"target_text" yaml:"target_text" toml:"target_text"`
}

Link represents a hyperlink found in a post's HTML content. It tracks both the source (where the link is from) and target (where it points to).

func NewLink(sourceURL, rawTarget, targetURL, targetDomain string, isInternal bool) *Link

NewLink creates a new Link with the given source and target information.

func (*Link) SourceSlug

func (l *Link) SourceSlug() string

SourceSlug returns the slug of the source post, or empty string if nil.

func (*Link) SourceTitle

func (l *Link) SourceTitle() string

SourceTitle returns the title of the source post, or empty string if nil.

func (*Link) TargetSlug

func (l *Link) TargetSlug() string

TargetSlug returns the slug of the target post, or empty string if nil.

func (*Link) TargetTitle

func (l *Link) TargetTitle() string

TargetTitle returns the title of the target post, or empty string if nil.

type LinkTag added in v0.3.0

type LinkTag struct {
	Rel         string `json:"rel" yaml:"rel" toml:"rel"`
	Href        string `json:"href" yaml:"href" toml:"href"`
	Crossorigin bool   `json:"crossorigin,omitempty" yaml:"crossorigin,omitempty" toml:"crossorigin,omitempty"`
}

LinkTag represents a <link> tag configuration.

type MDVideoConfig

type MDVideoConfig struct {
	// Enabled controls whether video conversion is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// VideoExtensions is the list of file extensions to treat as videos
	VideoExtensions []string `json:"video_extensions" yaml:"video_extensions" toml:"video_extensions"`

	// VideoClass is the CSS class added to video elements (default: "md-video")
	VideoClass string `json:"video_class" yaml:"video_class" toml:"video_class"`

	// Controls shows video controls (default: true)
	Controls bool `json:"controls" yaml:"controls" toml:"controls"`

	// Autoplay starts video automatically (default: true for GIF-like behavior)
	Autoplay bool `json:"autoplay" yaml:"autoplay" toml:"autoplay"`

	// Loop repeats the video (default: true for GIF-like behavior)
	Loop bool `json:"loop" yaml:"loop" toml:"loop"`

	// Muted mutes the video (default: true, required for autoplay in most browsers)
	Muted bool `json:"muted" yaml:"muted" toml:"muted"`

	// Playsinline enables inline playback on mobile (default: true)
	Playsinline bool `json:"playsinline" yaml:"playsinline" toml:"playsinline"`

	// Preload hints how much to preload: "none", "metadata", "auto" (default: "metadata")
	Preload string `json:"preload" yaml:"preload" toml:"preload"`
}

MDVideoConfig configures the md_video plugin.

func NewMDVideoConfig

func NewMDVideoConfig() MDVideoConfig

NewMDVideoConfig creates a new MDVideoConfig with sensible defaults. Default behavior is GIF-like: autoplay, loop, muted, with controls available.

type MarkdownConfig

type MarkdownConfig struct {
	// Extensions is the list of markdown extensions to enable
	Extensions []string `json:"extensions" yaml:"extensions" toml:"extensions"`

	// Highlight configures syntax highlighting for code blocks
	Highlight HighlightConfig `json:"highlight" yaml:"highlight" toml:"highlight"`
}

MarkdownConfig configures markdown processing.

type MentionMetadata added in v0.7.0

type MentionMetadata struct {
	// Domain is the normalized domain name (e.g., "example.com")
	Domain string `json:"domain"`

	// Name is the site name from og:site_name or title tag
	Name string `json:"name"`

	// Bio is the site description from og:description or meta description
	Bio string `json:"bio"`

	// Avatar is the avatar/image URL from og:image or icon
	Avatar string `json:"avatar"`

	// URL is the original URL that was fetched
	URL string `json:"url"`

	// LastFetched is when the metadata was last fetched
	LastFetched time.Time `json:"last_fetched"`

	// Error contains any error that occurred during fetching (empty if successful)
	Error string `json:"error,omitempty"`
}

MentionMetadata holds fetched metadata for a mention domain. This is cached between builds to avoid repeated network requests.

func (*MentionMetadata) IsExpired added in v0.7.0

func (m *MentionMetadata) IsExpired(maxAge time.Duration) bool

IsExpired checks if the cached metadata is older than the given duration.

func (*MentionMetadata) IsValid added in v0.7.0

func (m *MentionMetadata) IsValid() bool

IsValid returns true if the metadata was successfully fetched (no error).

type MentionPostSource added in v0.6.0

type MentionPostSource struct {
	// Filter is a filter expression to select which posts to extract handles from
	// Example: "'contact' in tags" or "template == 'team-member.html'"
	Filter string `json:"filter" yaml:"filter" toml:"filter"`

	// HandleField is the frontmatter field containing the handle (default: uses slug)
	// Example: "handle" for frontmatter like `handle: alice`
	HandleField string `json:"handle_field,omitempty" yaml:"handle_field,omitempty" toml:"handle_field,omitempty"`

	// AliasesField is the frontmatter field containing handle aliases (defaults to "aliases")
	// Example: "aliases" for frontmatter like `aliases: [alices, asmith]`
	AliasesField string `json:"aliases_field,omitempty" yaml:"aliases_field,omitempty" toml:"aliases_field,omitempty"`

	// AvatarField is the frontmatter field containing the avatar/image URL (optional).
	// If not set, looks for "avatar", "image", and "icon" fields in order.
	// This is used for mention hovercard display.
	AvatarField string `json:"avatar_field,omitempty" yaml:"avatar_field,omitempty" toml:"avatar_field,omitempty"`
}

MentionPostSource configures a source of @mentions from internal posts. This allows resolving @handles from posts like contact pages or team member pages.

type MentionsConfig added in v0.6.0

type MentionsConfig struct {
	// Enabled controls whether mentions processing is active (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// CSSClass is the CSS class applied to mention links (default: "mention")
	CSSClass string `json:"css_class,omitempty" yaml:"css_class,omitempty" toml:"css_class,omitempty"`

	// FromPosts configures mention sources from internal posts
	FromPosts []MentionPostSource `json:"from_posts,omitempty" yaml:"from_posts,omitempty" toml:"from_posts,omitempty"`

	// CacheDir is the directory for caching fetched mention metadata (default: "cache/mentions")
	CacheDir string `json:"cache_dir,omitempty" yaml:"cache_dir,omitempty" toml:"cache_dir,omitempty"`

	// CacheDuration is how long to cache fetched metadata (default: "24h")
	// Mentions change less frequently than RSS feeds, so use longer cache
	CacheDuration string `json:"cache_duration,omitempty" yaml:"cache_duration,omitempty" toml:"cache_duration,omitempty"`

	// Timeout is the HTTP request timeout in seconds for metadata fetching (default: 30)
	Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty" toml:"timeout,omitempty"`

	// ConcurrentRequests is the max concurrent metadata fetches (default: 3)
	// Lower than blogroll to be more respectful to external sites
	ConcurrentRequests int `json:"concurrent_requests,omitempty" yaml:"concurrent_requests,omitempty" toml:"concurrent_requests,omitempty"`
}

MentionsConfig configures the @mentions resolution plugin.

func NewMentionsConfig added in v0.6.0

func NewMentionsConfig() MentionsConfig

NewMentionsConfig creates a new MentionsConfig with default values.

func (*MentionsConfig) GetCSSClass added in v0.6.0

func (m *MentionsConfig) GetCSSClass() string

GetCSSClass returns the CSS class for mention links. Defaults to "mention" if not set.

func (*MentionsConfig) GetCacheDir added in v0.7.0

func (m *MentionsConfig) GetCacheDir() string

GetCacheDir returns the cache directory for mention metadata. Defaults to "cache/mentions" if not set.

func (*MentionsConfig) GetCacheDuration added in v0.7.0

func (m *MentionsConfig) GetCacheDuration() string

GetCacheDuration returns the cache duration for mention metadata. Defaults to "24h" if not set.

func (*MentionsConfig) GetConcurrentRequests added in v0.7.0

func (m *MentionsConfig) GetConcurrentRequests() int

GetConcurrentRequests returns the max concurrent metadata fetches. Defaults to 3 if not set.

func (*MentionsConfig) GetTimeout added in v0.7.0

func (m *MentionsConfig) GetTimeout() int

GetTimeout returns the HTTP timeout for metadata fetching. Defaults to 30 seconds if not set.

func (*MentionsConfig) IsEnabled added in v0.6.0

func (m *MentionsConfig) IsEnabled() bool

IsEnabled returns whether mentions processing is enabled. Defaults to true if not explicitly set.

type MermaidConfig

type MermaidConfig struct {
	// Enabled controls whether mermaid processing is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Mode specifies how to render diagrams: "client" (browser), "cli" (mmdc), or "chromium" (Chrome/Chromium)
	// Default: "client"
	Mode string `json:"mode" yaml:"mode" toml:"mode"`

	// CDNURL is the URL for the Mermaid.js library (client mode only)
	CDNURL string `json:"cdn_url" yaml:"cdn_url" toml:"cdn_url"`

	// Theme is the Mermaid theme to use (default, dark, forest, neutral)
	Theme string `json:"theme" yaml:"theme" toml:"theme"`

	// UseCSSVariables enables palette-aware theme variables from CSS custom properties.
	UseCSSVariables bool `json:"use_css_variables" yaml:"use_css_variables" toml:"use_css_variables"`

	// Lightbox enables GLightbox zoom for rendered Mermaid diagrams.
	Lightbox bool `json:"lightbox" yaml:"lightbox" toml:"lightbox"`

	// LightboxSelector is the CSS selector used for Mermaid lightbox links.
	LightboxSelector string `json:"lightbox_selector" yaml:"lightbox_selector" toml:"lightbox_selector"`

	// CLIConfig contains settings for CLI mode (npm mmdc)
	CLIConfig *CLIRendererConfig `json:"cli" yaml:"cli" toml:"cli"`

	// ChromiumConfig contains settings for Chromium mode (mermaidcdp)
	ChromiumConfig *ChromiumRendererConfig `json:"chromium" yaml:"chromium" toml:"chromium"`
}

MermaidConfig configures the mermaid plugin.

func NewMermaidConfig

func NewMermaidConfig() MermaidConfig

NewMermaidConfig creates a new MermaidConfig with default values.

type MermaidRenderError added in v0.7.0

type MermaidRenderError struct {
	Path       string
	DiagramID  string
	Mode       string
	Message    string
	Err        error
	Suggestion string
}

MermaidRenderError indicates an error rendering a Mermaid diagram.

func NewMermaidRenderError added in v0.7.0

func NewMermaidRenderError(path, mode, message string, err error) *MermaidRenderError

NewMermaidRenderError creates a new MermaidRenderError.

func (*MermaidRenderError) Error added in v0.7.0

func (e *MermaidRenderError) Error() string

func (*MermaidRenderError) Unwrap added in v0.7.0

func (e *MermaidRenderError) Unwrap() error

type MetaTag added in v0.3.0

type MetaTag struct {
	Name     string `json:"name,omitempty" yaml:"name,omitempty" toml:"name,omitempty"`
	Property string `json:"property,omitempty" yaml:"property,omitempty" toml:"property,omitempty"`
	Content  string `json:"content" yaml:"content" toml:"content"`
}

MetaTag represents a <meta> tag configuration.

type MultiFeedSection added in v0.4.0

type MultiFeedSection struct {
	// Feed is the feed slug to include in this section
	Feed string `json:"feed" yaml:"feed" toml:"feed"`

	// Title overrides the feed title for this section
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Collapsed starts this section collapsed (default: false for first, true for others)
	Collapsed *bool `json:"collapsed,omitempty" yaml:"collapsed,omitempty" toml:"collapsed,omitempty"`

	// MaxItems limits the number of items shown (0 = unlimited, default: 0)
	MaxItems int `json:"max_items,omitempty" yaml:"max_items,omitempty" toml:"max_items,omitempty"`
}

MultiFeedSection represents a section in a multi-feed sidebar.

func (*MultiFeedSection) IsCollapsed added in v0.4.0

func (m *MultiFeedSection) IsCollapsed() bool

IsCollapsed returns whether the section should start collapsed.

type NavComponentConfig struct {
	// Enabled controls whether navigation is displayed (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Position controls where navigation appears: "header", "sidebar" (default: "header")
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Style controls the navigation style: "horizontal", "vertical" (default: "horizontal")
	Style string `json:"style,omitempty" yaml:"style,omitempty" toml:"style,omitempty"`

	// Items are the navigation links (overrides top-level nav if set)
	Items []NavItem `json:"items,omitempty" yaml:"items,omitempty" toml:"items,omitempty"`
}

NavComponentConfig configures the navigation component.

type NavItem struct {
	// Label is the display text for the nav link
	Label string `json:"label" yaml:"label" toml:"label"`

	// URL is the link destination (can be relative or absolute)
	URL string `json:"url" yaml:"url" toml:"url"`

	// External indicates if the link opens in a new tab (default: false)
	External bool `json:"external,omitempty" yaml:"external,omitempty" toml:"external,omitempty"`
}

NavItem represents a navigation link.

type OEmbedProviderConfig added in v0.7.0

type OEmbedProviderConfig struct {
	// Enabled controls whether the provider is used (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Mode overrides the default embed mode for this provider.
	// Options: rich, card, performance, hover, image_only
	// When not set, the default is determined by the provider's oEmbed type:
	//   - photo: image_only
	//   - video: rich
	//   - rich: rich
	//   - link: card
	Mode string `json:"mode" yaml:"mode" toml:"mode"`
}

OEmbedProviderConfig configures a single oEmbed provider.

type OneLineLinkConfig added in v0.2.0

type OneLineLinkConfig struct {
	// Enabled controls whether link expansion is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// CardClass is the CSS class for the link card (default: "link-card")
	CardClass string `json:"card_class" yaml:"card_class" toml:"card_class"`

	// FetchMetadata enables fetching title/description from URLs (default: false for performance)
	FetchMetadata bool `json:"fetch_metadata" yaml:"fetch_metadata" toml:"fetch_metadata"`

	// FallbackTitle is used when metadata fetch fails (default: "Link")
	FallbackTitle string `json:"fallback_title" yaml:"fallback_title" toml:"fallback_title"`

	// Timeout is the HTTP request timeout in seconds (default: 5)
	Timeout int `json:"timeout" yaml:"timeout" toml:"timeout"`

	// ExcludePatterns is a list of regex patterns for URLs to exclude from expansion
	ExcludePatterns []string `json:"exclude_patterns" yaml:"exclude_patterns" toml:"exclude_patterns"`
}

OneLineLinkConfig configures the one_line_link plugin.

func NewOneLineLinkConfig added in v0.2.0

func NewOneLineLinkConfig() OneLineLinkConfig

NewOneLineLinkConfig creates a new OneLineLinkConfig with default values.

type OpenGraphTag added in v0.3.0

type OpenGraphTag struct {
	// Property is the og: property name (e.g., "og:title")
	Property string `json:"property" yaml:"property" toml:"property"`

	// Content is the tag content value
	Content string `json:"content" yaml:"content" toml:"content"`
}

OpenGraphTag represents an OpenGraph meta tag.

type PagefindConfig added in v0.3.0

type PagefindConfig struct {
	// BundleDir is the output directory for search index (default: "_pagefind")
	BundleDir string `json:"bundle_dir,omitempty" yaml:"bundle_dir,omitempty" toml:"bundle_dir,omitempty"`

	// ExcludeSelectors are CSS selectors for elements to exclude from indexing
	ExcludeSelectors []string `json:"exclude_selectors,omitempty" yaml:"exclude_selectors,omitempty" toml:"exclude_selectors,omitempty"`

	// RootSelector is the CSS selector for the searchable content container
	RootSelector string `json:"root_selector,omitempty" yaml:"root_selector,omitempty" toml:"root_selector,omitempty"`

	// AutoInstall enables automatic Pagefind binary installation (default: true)
	AutoInstall *bool `json:"auto_install,omitempty" yaml:"auto_install,omitempty" toml:"auto_install,omitempty"`

	// Version is the Pagefind version to install (default: "latest")
	Version string `json:"version,omitempty" yaml:"version,omitempty" toml:"version,omitempty"`

	// CacheDir is the directory for caching Pagefind binaries (default: XDG cache)
	CacheDir string `json:"cache_dir,omitempty" yaml:"cache_dir,omitempty" toml:"cache_dir,omitempty"`

	// Verbose enables verbose output from Pagefind (default: false)
	// When false, only errors are shown. When true or when --verbose CLI flag is used, all output is shown.
	Verbose *bool `json:"verbose,omitempty" yaml:"verbose,omitempty" toml:"verbose,omitempty"`
}

PagefindConfig configures Pagefind CLI behavior.

func (*PagefindConfig) IsAutoInstallEnabled added in v0.3.0

func (p *PagefindConfig) IsAutoInstallEnabled() bool

IsAutoInstallEnabled returns whether automatic Pagefind installation is enabled. Defaults to true if not explicitly set.

func (*PagefindConfig) IsVerbose added in v0.5.0

func (p *PagefindConfig) IsVerbose() bool

IsVerbose returns whether verbose output is enabled. Defaults to false if not explicitly set.

type PaginationType added in v0.3.0

type PaginationType string

PaginationType represents the type of pagination to use.

const (
	// PaginationManual uses traditional page links with full page reloads.
	PaginationManual PaginationType = "manual"

	// PaginationHTMX uses HTMX for seamless AJAX-based page loading.
	PaginationHTMX PaginationType = "htmx"

	// PaginationHTMXInfinite uses HTMX for infinite scroll pagination.
	PaginationHTMXInfinite PaginationType = "htmx-infinite"

	// PaginationJS uses client-side JavaScript for pagination.
	PaginationJS PaginationType = "js"
)

type PathSidebarConfig added in v0.4.0

type PathSidebarConfig struct {
	// Title is the optional sidebar title/header for this path
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// AutoGenerate configures auto-generation from directory structure
	AutoGenerate *SidebarAutoGenerate `json:"auto_generate,omitempty" yaml:"auto_generate,omitempty" toml:"auto_generate,omitempty"`

	// Items is the manual navigation structure for this path
	Items []SidebarNavItem `json:"items,omitempty" yaml:"items,omitempty" toml:"items,omitempty"`

	// Feed links this sidebar to a specific feed slug for auto-generation
	Feed string `json:"feed,omitempty" yaml:"feed,omitempty" toml:"feed,omitempty"`

	// Position overrides the default sidebar position for this path
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Collapsible overrides the default collapsible setting for this path
	Collapsible *bool `json:"collapsible,omitempty" yaml:"collapsible,omitempty" toml:"collapsible,omitempty"`
}

PathSidebarConfig configures a sidebar for a specific URL path prefix.

func (*PathSidebarConfig) IsCollapsible added in v0.4.0

func (p *PathSidebarConfig) IsCollapsible() bool

IsCollapsible returns whether the path sidebar is collapsible.

type PluginNotFoundError

type PluginNotFoundError struct {
	Name      string
	Available []string
}

PluginNotFoundError indicates a plugin was not found.

func NewPluginNotFoundError

func NewPluginNotFoundError(name string, available []string) *PluginNotFoundError

NewPluginNotFoundError creates a new PluginNotFoundError.

func (*PluginNotFoundError) Error

func (e *PluginNotFoundError) Error() string

type Post

type Post struct {
	// Path is the source file path
	Path string `json:"path" yaml:"path" toml:"path"`

	// Content is the raw markdown content after frontmatter
	Content string `json:"content" yaml:"content" toml:"content"`

	// Slug is the URL-safe identifier
	Slug string `json:"slug" yaml:"slug" toml:"slug"`

	// Href is the relative URL path (e.g., /my-post/)
	Href string `json:"href" yaml:"href" toml:"href"`

	// Title is the optional post title
	Title *string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Date is the optional publication date
	Date *time.Time `json:"date,omitempty" yaml:"date,omitempty" toml:"date,omitempty"`

	// Published indicates if the post is published
	Published bool `json:"published" yaml:"published" toml:"published"`

	// Draft indicates if the post is a draft
	Draft bool `json:"draft" yaml:"draft" toml:"draft"`

	// Private indicates if the post should be excluded from feeds and search
	// Private posts are rendered but excluded from feeds, sitemaps, and add noindex meta tag
	Private bool `json:"private" yaml:"private" toml:"private"`

	// SecretKey is the name of the encryption key to use for this post.
	// When set along with Private=true, the post content will be encrypted.
	// The actual key is read from environment variable MARKATA_GO_ENCRYPTION_KEY_{SecretKey}
	// Example: secret_key: "blog" reads from MARKATA_GO_ENCRYPTION_KEY_BLOG
	SecretKey string `json:"secret_key,omitempty" yaml:"secret_key,omitempty" toml:"secret_key,omitempty"`

	// Skip indicates if the post should be skipped during processing
	Skip bool `json:"skip" yaml:"skip" toml:"skip"`

	// Tags is a list of tags associated with the post
	Tags []string `json:"tags,omitempty" yaml:"tags,omitempty" toml:"tags,omitempty"`

	// Description is the optional post description
	Description *string `json:"description,omitempty" yaml:"description,omitempty" toml:"description,omitempty"`

	// Template is the template file to use for rendering (default: "post.html")
	// Can be a preset name ("blog", "docs") or explicit file ("post.html")
	Template string `json:"template" yaml:"template" toml:"template"`

	// Templates provides per-format template overrides
	// Keys: "html", "txt", "markdown", "og"
	// Values: template file names
	Templates map[string]string `json:"templates,omitempty" yaml:"templates,omitempty" toml:"templates,omitempty"`

	// HTML is the final rendered HTML including template wrapper
	HTML string `json:"html" yaml:"html" toml:"html"`

	// ArticleHTML is the rendered content without template wrapper
	ArticleHTML string `json:"article_html" yaml:"article_html" toml:"article_html"`

	// InputHash is a hash of the post's inputs (content + frontmatter + template)
	// Used for incremental builds to detect changes
	InputHash string `json:"input_hash,omitempty" yaml:"input_hash,omitempty" toml:"input_hash,omitempty"`

	// RawFrontmatter stores the original frontmatter string for hash computation
	// Not serialized to output
	RawFrontmatter string `json:"-" yaml:"-" toml:"-"`

	// Prev is the previous post in the navigation sequence
	Prev *Post `json:"-" yaml:"-" toml:"-"`

	// Next is the next post in the navigation sequence
	Next *Post `json:"-" yaml:"-" toml:"-"`

	// PrevNextFeed is the feed/series slug used for navigation
	PrevNextFeed string `json:"prevnext_feed,omitempty" yaml:"prevnext_feed,omitempty" toml:"prevnext_feed,omitempty"`

	// PrevNextContext contains full navigation context
	PrevNextContext *PrevNextContext `json:"-" yaml:"-" toml:"-"`

	// Hrefs is a list of raw href values from all links in the post
	Hrefs []string `json:"hrefs,omitempty" yaml:"hrefs,omitempty" toml:"hrefs,omitempty"`

	// Inlinks are links pointing TO this post from other posts
	Inlinks []*Link `json:"inlinks,omitempty" yaml:"inlinks,omitempty" toml:"inlinks,omitempty"`

	// Outlinks are links FROM this post to other pages
	Outlinks []*Link `json:"outlinks,omitempty" yaml:"outlinks,omitempty" toml:"outlinks,omitempty"`

	// Dependencies tracks slugs this post depends on (wikilinks, embeds).
	// Used for incremental build cache invalidation.
	// Not persisted to output files.
	Dependencies []string `json:"-" yaml:"-" toml:"-"`

	// Author fields (backward compatible)
	Authors []string `json:"authors,omitempty" yaml:"authors,omitempty" toml:"authors,omitempty"`
	Author  *string  `json:"author,omitempty" yaml:"author,omitempty" toml:"author,omitempty"` // Backward compatibility

	// Toc controls table of contents display for this post.
	// - nil: use global auto-enable logic or default
	// - true: force enable TOC for this post
	// - false: disable TOC for this post
	Toc *bool `json:"toc,omitempty" yaml:"toc,omitempty" toml:"toc,omitempty"`

	// TocPlaceholder indicates whether [[toc]] markdown placeholder was used.
	// When true, TOC will be rendered inline at the placeholder position.
	TocPlaceholder bool `json:"toc_placeholder,omitempty" yaml:"toc_placeholder,omitempty" toml:"toc_placeholder,omitempty"`

	// AuthorRoleOverrides stores per-post role overrides keyed by author ID.
	// Populated when frontmatter uses extended format: authors: [{id: waylon, role: editor}]
	// Not serialized; rebuilt from frontmatter on each load.
	AuthorRoleOverrides map[string]string `json:"-" yaml:"-" toml:"-"`

	// AuthorDetailsOverrides stores per-post details overrides keyed by author ID.
	// Populated when frontmatter uses extended format: authors: [{id: waylon, details: "wrote the intro"}]
	// Not serialized; rebuilt from frontmatter on each load.
	AuthorDetailsOverrides map[string]string `json:"-" yaml:"-" toml:"-"`

	// Extra holds dynamic/unknown fields from frontmatter
	Extra map[string]interface{} `json:"extra,omitempty" yaml:"extra,omitempty" toml:"extra,omitempty"`

	// Computed fields (not in frontmatter)
	AuthorObjects []Author `json:"-" yaml:"-" toml:"-"`
}

Post represents a single markdown post with its metadata and content.

func NewPost

func NewPost(path string) *Post

NewPost creates a new Post with the given source file path and default values.

func (*Post) AddDependency added in v0.6.0

func (p *Post) AddDependency(slug string)

AddDependency records that this post depends on the given slug. Used for incremental build cache invalidation. Thread-safe. Duplicates are allowed at collection time; deduplication happens when recording to cache.

func (*Post) GenerateHref

func (p *Post) GenerateHref()

GenerateHref generates the relative URL path from the slug. The href follows the pattern /{slug}/ or / for empty slug (homepage). Note: This method assumes the slug is already set. Use GenerateSlug() first if automatic slug generation is needed.

func (*Post) GenerateSlug

func (p *Post) GenerateSlug()

GenerateSlug generates a URL-safe slug from the title or path. If a title is set, it uses the title; otherwise, it derives the slug from the file path.

Special handling for index.md files:

  • ./index.md → "" (empty slug, becomes homepage)
  • docs/index.md → "docs"
  • blog/guides/index.md → "blog/guides"

func (*Post) Get

func (p *Post) Get(key string) interface{}

Get retrieves a value from the Extra map by key. Returns nil if the key does not exist.

func (*Post) GetAuthors added in v0.7.0

func (p *Post) GetAuthors() []string

GetAuthors returns a list of author IDs for this post. Prefers the Authors array if available, falls back to single Author field.

func (*Post) Has

func (p *Post) Has(key string) bool

Has checks if a key exists in the Extra map.

func (*Post) HasAuthor added in v0.7.0

func (p *Post) HasAuthor(authorID string) bool

HasAuthor checks if the post has the specified author ID.

func (*Post) HasTocOverride added in v0.7.0

func (p *Post) HasTocOverride() bool

HasTocOverride returns true if the post has an explicit TOC setting in frontmatter.

func (*Post) IsTocEnabled added in v0.7.0

func (p *Post) IsTocEnabled(tocConfig *TocConfig, tocLinkCount, wordCount int) bool

IsTocEnabled returns true if TOC should be displayed for this post. The tocConfig is the global configuration to use for auto-enable logic.

func (*Post) Set

func (p *Post) Set(key string, value interface{})

Set sets a value in the Extra map. Initializes the Extra map if it is nil.

func (*Post) SetAuthors added in v0.7.0

func (p *Post) SetAuthors(authors interface{})

SetAuthors sets the authors for this post. Accepts either a single string (for backward compatibility), an array of strings, or a mixed array where items can be strings or maps with "id" and optional "role". Per-post role overrides from map entries are stored in AuthorRoleOverrides.

type PostFormatsConfig added in v0.3.0

type PostFormatsConfig struct {
	// HTML enables standard HTML output (default: true)
	// Generates: /slug/index.html
	HTML *bool `json:"html,omitempty" yaml:"html,omitempty" toml:"html,omitempty"`

	// Markdown enables raw markdown output (default: false)
	// Generates: /slug.md (source with frontmatter)
	Markdown bool `json:"markdown" yaml:"markdown" toml:"markdown"`

	// Text enables plain text output (default: false)
	// Generates: /slug.txt (content only, no formatting)
	Text bool `json:"text" yaml:"text" toml:"text"`

	// OG enables OpenGraph card HTML output for social image generation (default: false)
	// Generates: /slug/og/index.html (1200x630 optimized for screenshots)
	OG bool `json:"og" yaml:"og" toml:"og"`
}

PostFormatsConfig configures the output formats for individual posts. This controls what file formats are generated for each post.

func NewPostFormatsConfig added in v0.3.0

func NewPostFormatsConfig() PostFormatsConfig

NewPostFormatsConfig creates a new PostFormatsConfig with default values. By default, all post output formats are enabled.

func (*PostFormatsConfig) IsHTMLEnabled added in v0.3.0

func (p *PostFormatsConfig) IsHTMLEnabled() bool

IsHTMLEnabled returns whether HTML output is enabled. Defaults to true if not explicitly set.

type PostProcessingError

type PostProcessingError struct {
	Path    string
	Stage   string
	Message string
	Err     error
}

PostProcessingError indicates an error during post processing.

func NewPostProcessingError

func NewPostProcessingError(path, stage, message string, err error) *PostProcessingError

NewPostProcessingError creates a new PostProcessingError.

func (*PostProcessingError) Error

func (e *PostProcessingError) Error() string

func (*PostProcessingError) Unwrap

func (e *PostProcessingError) Unwrap() error

type PrevNextConfig

type PrevNextConfig struct {
	// Enabled controls whether the plugin is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Strategy determines how prev/next links are resolved
	Strategy PrevNextStrategy `json:"strategy" yaml:"strategy" toml:"strategy"`

	// DefaultFeed is the feed slug to use when strategy is "explicit_feed"
	DefaultFeed string `json:"default_feed" yaml:"default_feed" toml:"default_feed"`
}

PrevNextConfig holds configuration for the prevnext plugin.

func NewPrevNextConfig

func NewPrevNextConfig() PrevNextConfig

NewPrevNextConfig creates a new PrevNextConfig with default values.

func (*PrevNextConfig) ApplyDefaults

func (c *PrevNextConfig) ApplyDefaults()

ApplyDefaults ensures all required fields have sensible defaults.

type PrevNextContext

type PrevNextContext struct {
	// FeedSlug is the feed or series slug used for navigation
	FeedSlug string `json:"feed_slug" yaml:"feed_slug" toml:"feed_slug"`

	// FeedTitle is the feed or series title
	FeedTitle string `json:"feed_title" yaml:"feed_title" toml:"feed_title"`

	// Position is the 1-indexed position of the post in the sequence
	Position int `json:"position" yaml:"position" toml:"position"`

	// Total is the total number of posts in the sequence
	Total int `json:"total" yaml:"total" toml:"total"`

	// Prev is the previous post in the sequence (nil if first)
	Prev *Post `json:"prev,omitempty" yaml:"prev,omitempty" toml:"prev,omitempty"`

	// Next is the next post in the sequence (nil if last)
	Next *Post `json:"next,omitempty" yaml:"next,omitempty" toml:"next,omitempty"`
}

PrevNextContext contains navigation context for a post.

func (*PrevNextContext) HasNext

func (c *PrevNextContext) HasNext() bool

HasNext returns true if there is a next post.

func (*PrevNextContext) HasPrev

func (c *PrevNextContext) HasPrev() bool

HasPrev returns true if there is a previous post.

func (*PrevNextContext) IsFirst

func (c *PrevNextContext) IsFirst() bool

IsFirst returns true if this is the first post in the sequence.

func (*PrevNextContext) IsLast

func (c *PrevNextContext) IsLast() bool

IsLast returns true if this is the last post in the sequence.

type PrevNextStrategy

type PrevNextStrategy string

PrevNextStrategy defines how prev/next links are calculated.

const (
	// StrategyFirstFeed uses the first feed the post appears in.
	StrategyFirstFeed PrevNextStrategy = "first_feed"

	// StrategyExplicitFeed always uses the configured default_feed.
	StrategyExplicitFeed PrevNextStrategy = "explicit_feed"

	// StrategySeries uses the post's series frontmatter, falling back to first_feed.
	StrategySeries PrevNextStrategy = "series"

	// StrategyFrontmatter uses the post's prevnext_feed frontmatter, falling back to first_feed.
	StrategyFrontmatter PrevNextStrategy = "frontmatter"
)

func (PrevNextStrategy) IsValid

func (s PrevNextStrategy) IsValid() bool

IsValid returns true if the strategy is a recognized value.

type QRCodeConfig added in v0.2.0

type QRCodeConfig struct {
	// Enabled controls whether QR codes are generated (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Format is the output format: "svg" or "png" (default: "svg")
	Format string `json:"format" yaml:"format" toml:"format"`

	// Size is the QR code size in pixels (default: 200)
	Size int `json:"size" yaml:"size" toml:"size"`

	// OutputDir is the subdirectory in output for QR code files (default: "qrcodes")
	OutputDir string `json:"output_dir" yaml:"output_dir" toml:"output_dir"`

	// ErrorCorrection is the QR error correction level: L, M, Q, H (default: "M")
	ErrorCorrection string `json:"error_correction" yaml:"error_correction" toml:"error_correction"`

	// Foreground is the QR code foreground color in hex (default: "#000000")
	Foreground string `json:"foreground" yaml:"foreground" toml:"foreground"`

	// Background is the QR code background color in hex (default: "#ffffff")
	Background string `json:"background" yaml:"background" toml:"background"`
}

QRCodeConfig configures the qrcode plugin.

func NewQRCodeConfig added in v0.2.0

func NewQRCodeConfig() QRCodeConfig

NewQRCodeConfig creates a new QRCodeConfig with default values.

type ReaderPage added in v0.5.0

type ReaderPage struct {
	// Number is the page number (1-indexed)
	Number int `json:"number" yaml:"number" toml:"number"`

	// Entries is the list of entries on this page
	Entries []*ExternalEntry `json:"entries" yaml:"entries" toml:"entries"`

	// HasPrev indicates if there is a previous page
	HasPrev bool `json:"has_prev" yaml:"has_prev" toml:"has_prev"`

	// HasNext indicates if there is a next page
	HasNext bool `json:"has_next" yaml:"has_next" toml:"has_next"`

	// PrevURL is the URL of the previous page
	PrevURL string `json:"prev_url" yaml:"prev_url" toml:"prev_url"`

	// NextURL is the URL of the next page
	NextURL string `json:"next_url" yaml:"next_url" toml:"next_url"`

	// TotalPages is the total number of pages
	TotalPages int `json:"total_pages" yaml:"total_pages" toml:"total_pages"`

	// TotalItems is the total number of entries
	TotalItems int `json:"total_items" yaml:"total_items" toml:"total_items"`

	// ItemsPerPage is the number of entries per page
	ItemsPerPage int `json:"items_per_page" yaml:"items_per_page" toml:"items_per_page"`

	// PageURLs contains URLs for all pages (for numbered pagination)
	PageURLs []string `json:"page_urls" yaml:"page_urls" toml:"page_urls"`

	// PaginationType is the pagination strategy used
	PaginationType PaginationType `json:"pagination_type" yaml:"pagination_type" toml:"pagination_type"`
}

ReaderPage represents a single page of paginated reader entries.

type ResourceHintsConfig added in v0.7.0

type ResourceHintsConfig struct {
	// Enabled controls whether resource hints are generated (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// AutoDetect enables automatic detection of external domains in HTML/CSS (default: true)
	AutoDetect *bool `json:"auto_detect,omitempty" yaml:"auto_detect,omitempty" toml:"auto_detect,omitempty"`

	// Domains is a list of manually configured domain hints
	Domains []DomainHint `json:"domains,omitempty" yaml:"domains,omitempty" toml:"domains,omitempty"`

	// ExcludeDomains is a list of domains to exclude from auto-detection
	ExcludeDomains []string `json:"exclude_domains,omitempty" yaml:"exclude_domains,omitempty" toml:"exclude_domains,omitempty"`
}

ResourceHintsConfig configures automatic resource hints generation for network optimization. Resource hints (preconnect, dns-prefetch, preload, prefetch) help browsers prepare for external resources before they're needed, improving page load performance.

func NewResourceHintsConfig added in v0.7.0

func NewResourceHintsConfig() ResourceHintsConfig

NewResourceHintsConfig creates a new ResourceHintsConfig with default values.

func (*ResourceHintsConfig) IsAutoDetectEnabled added in v0.7.0

func (r *ResourceHintsConfig) IsAutoDetectEnabled() bool

IsAutoDetectEnabled returns whether auto-detection is enabled. Defaults to true if not explicitly set.

func (*ResourceHintsConfig) IsEnabled added in v0.7.0

func (r *ResourceHintsConfig) IsEnabled() bool

IsEnabled returns whether resource hints generation is enabled. Defaults to true if not explicitly set.

type ResourceLoadingMode added in v0.7.0

type ResourceLoadingMode struct {
	// Loading controls when the resource is fetched:
	// - "lazy" (default): Load on first user interaction (hover, focus, keyboard shortcut)
	// - "eager": Load immediately on page load
	Loading string `json:"loading,omitempty" yaml:"loading,omitempty" toml:"loading,omitempty"`
}

ResourceLoadingMode configures when a specific resource is loaded.

type ResourcesConfig added in v0.7.0

type ResourcesConfig struct {
	// Strategy controls the overall resource loading approach:
	// - "conditional" (default): Load resources only when page content requires them
	// - "eager": Load all resources on every page (legacy behavior, simpler but slower)
	Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty" toml:"strategy,omitempty"`

	// ForceLoad is a list of resource base names to always load regardless of content.
	// Useful when custom templates use CSS classes that build-time detection can't see.
	// Example: ["admonitions", "code", "cards"]
	// Valid names: admonitions, code, chroma, cards, webmentions, encryption
	ForceLoad []string `json:"force_load,omitempty" yaml:"force_load,omitempty" toml:"force_load,omitempty"`

	// Search configures search resource loading behavior.
	Search ResourceLoadingMode `json:"search,omitempty" yaml:"search,omitempty" toml:"search,omitempty"`

	// GLightbox configures GLightbox resource loading behavior.
	GLightbox ResourceLoadingMode `json:"glightbox,omitempty" yaml:"glightbox,omitempty" toml:"glightbox,omitempty"`
}

ResourcesConfig configures conditional resource loading behavior. By default, CSS and JS resources are loaded conditionally based on page content detection (e.g., admonitions.css only loads when a page has admonitions). This config allows overriding that behavior.

func NewResourcesConfig added in v0.7.0

func NewResourcesConfig() ResourcesConfig

NewResourcesConfig creates a new ResourcesConfig with default values.

func (*ResourcesConfig) IsConditional added in v0.7.0

func (r *ResourcesConfig) IsConditional() bool

IsConditional returns true if resources should be loaded conditionally.

func (*ResourcesConfig) IsForceLoaded added in v0.7.0

func (r *ResourcesConfig) IsForceLoaded(name string) bool

IsForceLoaded returns true if a resource should always be loaded.

type SEOConfig added in v0.3.0

type SEOConfig struct {
	// TwitterHandle is the Twitter/X username (without @) for twitter:site meta tag
	TwitterHandle string `json:"twitter_handle" yaml:"twitter_handle" toml:"twitter_handle"`

	// DefaultImage is the default Open Graph image URL for pages without a specific image
	DefaultImage string `json:"default_image" yaml:"default_image" toml:"default_image"`

	// LogoURL is the site logo URL for Schema.org structured data
	LogoURL string `json:"logo_url" yaml:"logo_url" toml:"logo_url"`

	// AuthorImage is the author's profile image URL for OG cards
	AuthorImage string `json:"author_image" yaml:"author_image" toml:"author_image"`

	// OGImageService is the URL for a screenshot service that generates OG images
	// from OG card pages. The URL should accept a `url` query parameter.
	// Example: "https://shots.example.com/shot/" generates URLs like:
	// "https://shots.example.com/shot/?url=https://site.com/post/og/&height=600&width=1200&format=jpg"
	OGImageService string `json:"og_image_service" yaml:"og_image_service" toml:"og_image_service"`

	// StructuredData configures JSON-LD Schema.org generation
	StructuredData StructuredDataConfig `json:"structured_data" yaml:"structured_data" toml:"structured_data"`
}

SEOConfig configures SEO metadata for the site.

func NewSEOConfig added in v0.3.0

func NewSEOConfig() SEOConfig

NewSEOConfig creates a new SEOConfig with default values.

type SchemaAgent added in v0.3.0

type SchemaAgent struct {
	Type string       `json:"@type"`
	Name string       `json:"name"`
	URL  string       `json:"url,omitempty"`
}

SchemaAgent represents a Schema.org Person or Organization.

func NewSchemaAgent added in v0.3.0

func NewSchemaAgent(agentType, name string) *SchemaAgent

NewSchemaAgent creates a new SchemaAgent (Person or Organization).

func (a *SchemaAgent) WithLogo(logoURL string) *SchemaAgent

WithLogo sets the logo on a SchemaAgent and returns it for chaining.

func (*SchemaAgent) WithURL added in v0.3.0

func (a *SchemaAgent) WithURL(url string) *SchemaAgent

WithURL sets the URL on a SchemaAgent and returns it for chaining.

type ScriptTag added in v0.3.0

type ScriptTag struct {
	Src string `json:"src" yaml:"src" toml:"src"`
}

ScriptTag represents a <script> tag configuration.

type SearchConfig added in v0.3.0

type SearchConfig struct {
	// Enabled controls whether search is active (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Position controls where search UI appears: "navbar", "sidebar", "footer", "custom"
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Placeholder is the search input placeholder text
	Placeholder string `json:"placeholder,omitempty" yaml:"placeholder,omitempty" toml:"placeholder,omitempty"`

	// ShowImages shows thumbnails in search results
	ShowImages *bool `json:"show_images,omitempty" yaml:"show_images,omitempty" toml:"show_images,omitempty"`

	// ExcerptLength is the character limit for result excerpts
	ExcerptLength int `json:"excerpt_length,omitempty" yaml:"excerpt_length,omitempty" toml:"excerpt_length,omitempty"`

	// Pagefind configures the Pagefind CLI options
	Pagefind PagefindConfig `json:"pagefind,omitempty" yaml:"pagefind,omitempty" toml:"pagefind,omitempty"`

	// Feeds configures feed-specific search instances
	Feeds []SearchFeedConfig `json:"feeds,omitempty" yaml:"feeds,omitempty" toml:"feeds,omitempty"`
}

SearchConfig configures site-wide search functionality using Pagefind.

func NewSearchConfig added in v0.3.0

func NewSearchConfig() SearchConfig

NewSearchConfig creates a new SearchConfig with default values.

func (*SearchConfig) IsEnabled added in v0.3.0

func (s *SearchConfig) IsEnabled() bool

IsEnabled returns whether search is enabled. Defaults to true if not explicitly set.

func (*SearchConfig) IsShowImages added in v0.3.0

func (s *SearchConfig) IsShowImages() bool

IsShowImages returns whether to show images in search results. Defaults to true if not explicitly set.

type SearchFeedConfig added in v0.3.0

type SearchFeedConfig struct {
	// Name is the search instance identifier
	Name string `json:"name" yaml:"name" toml:"name"`

	// Filter is the filter expression for posts in this search
	Filter string `json:"filter" yaml:"filter" toml:"filter"`

	// Position controls where this search UI appears
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Placeholder is the search input placeholder text
	Placeholder string `json:"placeholder,omitempty" yaml:"placeholder,omitempty" toml:"placeholder,omitempty"`
}

SearchFeedConfig configures a feed-specific search instance.

type ShareButton added in v0.7.0

type ShareButton struct {
	Key              string
	Name             string
	Icon             string
	IconIsThemeAsset bool
	Action           string
	Link             string
	CopyText         string
	AriaLabel        string
	CopyFeedback     string
}

ShareButton exposes data required by share templates.

func BuildShareButtons added in v0.7.0

func BuildShareButtons(cfg ShareComponentConfig, baseURL, fallbackTitle string, post *Post) []ShareButton

BuildShareButtons creates the share buttons for a specific post using the current config.

type ShareComponentConfig added in v0.7.0

type ShareComponentConfig struct {
	// Enabled toggles the entire component (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Platforms controls which platform keys render and in what order
	Platforms []string `json:"platforms,omitempty" yaml:"platforms,omitempty" toml:"platforms,omitempty"`

	// Position adds `share-panel--<position>` modifier for CSS hooks
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Title is the heading text displayed above the buttons
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Custom maps platform keys to bespoke definitions
	Custom map[string]SharePlatformConfig `json:"custom,omitempty" yaml:"custom,omitempty" toml:"custom,omitempty"`
}

ShareComponentConfig configures the share buttons that appear at the end of posts.

func NewShareComponentConfig added in v0.7.0

func NewShareComponentConfig() ShareComponentConfig

NewShareComponentConfig returns the default share component configuration.

func (ShareComponentConfig) IsEnabled added in v0.7.0

func (c ShareComponentConfig) IsEnabled() bool

IsEnabled reports whether the share component is enabled.

type SharePlatformConfig added in v0.7.0

type SharePlatformConfig struct {
	// Name is the accessible label for the platform button
	Name string `json:"name,omitempty" yaml:"name,omitempty" toml:"name,omitempty"`

	// Icon is the path to an icon file (relative to theme assets by default)
	Icon string `json:"icon,omitempty" yaml:"icon,omitempty" toml:"icon,omitempty"`

	// URL is the share URL template (supports {{title}}, {{url}}, {{excerpt}})
	URL string `json:"url,omitempty" yaml:"url,omitempty" toml:"url,omitempty"`
}

SharePlatformConfig defines a custom share button entry.

type ShortcutsConfig added in v0.7.0

type ShortcutsConfig struct {
	// Navigation contains shortcuts for navigating to specific pages.
	// Keys are key sequences (e.g., "g t"), values are destination URLs.
	// Example: {"g t": "/tags/", "g a": "/about/"}
	Navigation map[string]string `json:"navigation,omitempty" yaml:"navigation,omitempty" toml:"navigation,omitempty"`
}

ShortcutsConfig configures user-defined keyboard shortcuts. Shortcuts are organized by group (e.g., "navigation") and map key sequences to URLs.

func NewShortcutsConfig added in v0.7.0

func NewShortcutsConfig() ShortcutsConfig

NewShortcutsConfig creates a new ShortcutsConfig with default values.

func (*ShortcutsConfig) HasCustomShortcuts added in v0.7.0

func (s *ShortcutsConfig) HasCustomShortcuts() bool

HasCustomShortcuts returns true if any custom shortcuts are defined.

type SidebarAutoGenerate added in v0.4.0

type SidebarAutoGenerate struct {
	// Directory is the source directory for auto-generation (relative to content root)
	Directory string `json:"directory,omitempty" yaml:"directory,omitempty" toml:"directory,omitempty"`

	// OrderBy specifies how to order items: "title", "date", "nav_order", "filename" (default: "filename")
	OrderBy string `json:"order_by,omitempty" yaml:"order_by,omitempty" toml:"order_by,omitempty"`

	// Reverse reverses the sort order (default: false)
	Reverse *bool `json:"reverse,omitempty" yaml:"reverse,omitempty" toml:"reverse,omitempty"`

	// MaxDepth limits how deep to recurse into subdirectories (0 = unlimited, default: 0)
	MaxDepth int `json:"max_depth,omitempty" yaml:"max_depth,omitempty" toml:"max_depth,omitempty"`

	// Exclude is a list of glob patterns to exclude from auto-generation
	Exclude []string `json:"exclude,omitempty" yaml:"exclude,omitempty" toml:"exclude,omitempty"`
}

SidebarAutoGenerate configures automatic sidebar generation from a directory or feed.

func (*SidebarAutoGenerate) IsReverse added in v0.4.0

func (a *SidebarAutoGenerate) IsReverse() bool

IsReverse returns whether to reverse the sort order.

type SidebarConfig added in v0.4.0

type SidebarConfig struct {
	// Enabled controls whether the sidebar is displayed (default: true for docs layout)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Position controls sidebar placement: "left" or "right" (default: "left")
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Width is the sidebar width (default: "280px")
	Width string `json:"width,omitempty" yaml:"width,omitempty" toml:"width,omitempty"`

	// Collapsible allows the sidebar to be collapsed (default: true)
	Collapsible *bool `json:"collapsible,omitempty" yaml:"collapsible,omitempty" toml:"collapsible,omitempty"`

	// DefaultOpen controls if sidebar is open by default (default: true)
	DefaultOpen *bool `json:"default_open,omitempty" yaml:"default_open,omitempty" toml:"default_open,omitempty"`

	// Nav is the navigation structure (auto-generated from feeds if not specified)
	Nav []SidebarNavItem `json:"nav,omitempty" yaml:"nav,omitempty" toml:"nav,omitempty"`

	// Title is the optional sidebar title/header
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Paths maps URL path prefixes to path-specific sidebar configs
	// Keys should be paths like "/docs/", "/blog/", "/guides/"
	Paths map[string]*PathSidebarConfig `json:"paths,omitempty" yaml:"paths,omitempty" toml:"paths,omitempty"`

	// MultiFeed enables multi-feed mode with collapsible sections
	MultiFeed *bool `json:"multi_feed,omitempty" yaml:"multi_feed,omitempty" toml:"multi_feed,omitempty"`

	// Feeds is the list of feed slugs to show in multi-feed mode
	Feeds []string `json:"feeds,omitempty" yaml:"feeds,omitempty" toml:"feeds,omitempty"`

	// FeedSections provides detailed config for multi-feed sections
	FeedSections []MultiFeedSection `json:"feed_sections,omitempty" yaml:"feed_sections,omitempty" toml:"feed_sections,omitempty"`

	// AutoGenerate configures default auto-generation settings
	AutoGenerate *SidebarAutoGenerate `json:"auto_generate,omitempty" yaml:"auto_generate,omitempty" toml:"auto_generate,omitempty"`
}

SidebarConfig configures the sidebar navigation component.

func NewSidebarConfig added in v0.4.0

func NewSidebarConfig() SidebarConfig

NewSidebarConfig creates a new SidebarConfig with default values.

func (*SidebarConfig) GetEffectiveConfig added in v0.4.0

func (s *SidebarConfig) GetEffectiveConfig(path string) *SidebarConfig

GetEffectiveConfig returns an effective sidebar configuration for a path, merging path-specific settings with the default sidebar config.

func (*SidebarConfig) IsCollapsible added in v0.4.0

func (s *SidebarConfig) IsCollapsible() bool

IsCollapsible returns whether the sidebar can be collapsed.

func (*SidebarConfig) IsDefaultOpen added in v0.4.0

func (s *SidebarConfig) IsDefaultOpen() bool

IsDefaultOpen returns whether the sidebar is open by default.

func (*SidebarConfig) IsEnabled added in v0.4.0

func (s *SidebarConfig) IsEnabled() bool

IsEnabled returns whether the sidebar is enabled.

func (*SidebarConfig) IsMultiFeed added in v0.4.0

func (s *SidebarConfig) IsMultiFeed() bool

IsMultiFeed returns whether multi-feed mode is enabled.

func (*SidebarConfig) ResolveForPath added in v0.4.0

func (s *SidebarConfig) ResolveForPath(path string) (*PathSidebarConfig, bool)

ResolveForPath finds the best matching sidebar configuration for a given path. It checks path-specific sidebars and returns the most specific match (longest prefix wins). Returns the matching PathSidebarConfig and true if found, or nil and false otherwise.

type SidebarNavItem added in v0.4.0

type SidebarNavItem struct {
	// Title is the display text for the navigation item
	Title string `json:"title" yaml:"title" toml:"title"`

	// Href is the link destination (can be relative or absolute)
	Href string `json:"href,omitempty" yaml:"href,omitempty" toml:"href,omitempty"`

	// Children are nested navigation items
	Children []SidebarNavItem `json:"children,omitempty" yaml:"children,omitempty" toml:"children,omitempty"`
}

SidebarNavItem represents a navigation item in the sidebar.

type SteamAchievement added in v0.6.0

type SteamAchievement struct {
	// APIName is the internal achievement API name
	APIName string `json:"apiname" yaml:"apiname" toml:"apiname"`

	// Name is the display name of the achievement
	Name *string `json:"name,omitempty" yaml:"name,omitempty" toml:"name,omitempty"`

	// Description is the achievement description
	Description *string `json:"description,omitempty" yaml:"description,omitempty" toml:"description,omitempty"`

	// Icon is the URL to the achievement icon
	Icon *string `json:"icon,omitempty" yaml:"icon,omitempty" toml:"icon,omitempty"`

	// IconGray is the URL to the grayed out achievement icon
	IconGray *string `json:"icongray,omitempty" yaml:"icongray,omitempty" toml:"icongray,omitempty"`

	// Achieved indicates if the achievement is unlocked (1 or 0)
	Achieved int `json:"achieved" yaml:"achieved" toml:"achieved"`

	// UnlockTime is the timestamp when the achievement was unlocked
	UnlockTime *int64 `json:"unlocktime,omitempty" yaml:"unlocktime,omitempty" toml:"unlocktime,omitempty"`
}

SteamAchievement represents a Steam achievement.

func (*SteamAchievement) IsUnlocked added in v0.6.0

func (sa *SteamAchievement) IsUnlocked() bool

IsUnlocked returns true if the achievement is unlocked.

func (*SteamAchievement) UnlockDate added in v0.6.0

func (sa *SteamAchievement) UnlockDate() *time.Time

UnlockDate returns the unlock date as a time.Time, or nil if not unlocked.

type SteamConfig added in v0.6.0

type SteamConfig struct {
	// APIKey is the Steam Web API key (required)
	APIKey string `json:"api_key" yaml:"api_key" toml:"api_key" env:"STEAM_API_KEY"`

	// SteamID is the user's Steam ID (required)
	SteamID string `json:"steam_id" yaml:"steam_id" toml:"steam_id" env:"STEAM_ID"`

	// PostsDir is the directory to create achievement posts (default: "pages/steam")
	PostsDir string `json:"posts_dir,omitempty" yaml:"posts_dir,omitempty" toml:"posts_dir,omitempty"`

	// Template is the template name to use for steam posts (default: "steam_achievement")
	Template string `json:"template,omitempty" yaml:"template,omitempty" toml:"template,omitempty"`

	// CacheDuration is cache duration in seconds (default: 3600)
	CacheDuration int `json:"cache_duration,omitempty" yaml:"cache_duration,omitempty" toml:"cache_duration,omitempty"`

	// MinPlaytimeHours is minimum playtime in hours to include games (default: 3)
	MinPlaytimeHours float64 `json:"min_playtime_hours,omitempty" yaml:"min_playtime_hours,omitempty" toml:"min_playtime_hours,omitempty"`

	// Enabled enables the plugin (default: false)
	Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`
}

SteamConfig represents configuration for the Steam achievements plugin.

func NewSteamConfig added in v0.6.0

func NewSteamConfig() SteamConfig

NewSteamConfig returns a new SteamConfig with default values.

type SteamGame added in v0.6.0

type SteamGame struct {
	// AppID is the Steam application ID
	AppID int `json:"appid" yaml:"appid" toml:"appid"`

	// Name is the game name
	Name string `json:"name" yaml:"name" toml:"name"`

	// Description is the game description
	Description *string `json:"description,omitempty" yaml:"description,omitempty" toml:"description,omitempty"`

	// Developers are the game developers
	Developers []string `json:"developers,omitempty" yaml:"developers,omitempty" toml:"developers,omitempty"`

	// Publishers are the game publishers
	Publishers []string `json:"publishers,omitempty" yaml:"publishers,omitempty" toml:"publishers,omitempty"`

	// Achievements is the list of achievements
	Achievements []SteamAchievement `json:"achievements" yaml:"achievements" toml:"achievements"`

	// TotalAchievements is the total number of achievements
	TotalAchievements int `json:"total_achievements" yaml:"total_achievements" toml:"total_achievements"`

	// UnlockedAchievements is the number of unlocked achievements
	UnlockedAchievements int `json:"unlocked_achievements" yaml:"unlocked_achievements" toml:"unlocked_achievements"`

	// CompletionPercentage is the percentage of achievements completed
	CompletionPercentage float64 `json:"completion_percentage" yaml:"completion_percentage" toml:"completion_percentage"`

	// PlaytimeForever is total playtime in minutes
	PlaytimeForever *int `json:"playtime_forever,omitempty" yaml:"playtime_forever,omitempty" toml:"playtime_forever,omitempty"`

	// Playtime2Weeks is playtime in the last 2 weeks in minutes
	Playtime2Weeks *int `json:"playtime_2weeks,omitempty" yaml:"playtime_2weeks,omitempty" toml:"playtime_2weeks,omitempty"`

	// LastPlayed is the timestamp when the game was last played
	LastPlayed *int64 `json:"last_played,omitempty" yaml:"last_played,omitempty" toml:"last_played,omitempty"`
}

SteamGame represents a Steam game with achievement data.

func (*SteamGame) LastPlayedDate added in v0.6.0

func (sg *SteamGame) LastPlayedDate() *time.Time

LastPlayedDate returns the last played date as a time.Time, or nil if never played.

func (*SteamGame) LockedAchievementsList added in v0.6.0

func (sg *SteamGame) LockedAchievementsList() []SteamAchievement

LockedAchievementsList returns a list of locked achievements.

func (*SteamGame) PlaytimeHours added in v0.6.0

func (sg *SteamGame) PlaytimeHours() float64

PlaytimeHours returns the total playtime in hours.

func (*SteamGame) ShouldInclude added in v0.6.0

func (sg *SteamGame) ShouldInclude(minHours float64) bool

ShouldInclude returns true if the game meets the minimum playtime requirement.

func (*SteamGame) UnlockedAchievementsList added in v0.6.0

func (sg *SteamGame) UnlockedAchievementsList() []SteamAchievement

UnlockedAchievementsList returns a list of unlocked achievements.

type StructuredData added in v0.3.0

type StructuredData struct {
	// JSONLD is the JSON-LD script content (without script tags)
	JSONLD string `json:"jsonld" yaml:"jsonld" toml:"jsonld"`

	// OpenGraph contains OpenGraph meta tags
	OpenGraph []OpenGraphTag `json:"opengraph" yaml:"opengraph" toml:"opengraph"`

	// Twitter contains Twitter Card meta tags
	Twitter []TwitterTag `json:"twitter" yaml:"twitter" toml:"twitter"`
}

StructuredData holds generated structured data for a post. This is stored in post.Extra["structured_data"] after processing.

func NewStructuredData added in v0.3.0

func NewStructuredData() *StructuredData

NewStructuredData creates a new empty StructuredData.

func (*StructuredData) AddOpenGraph added in v0.3.0

func (s *StructuredData) AddOpenGraph(property, content string)

AddOpenGraph adds an OpenGraph tag.

func (*StructuredData) AddTwitter added in v0.3.0

func (s *StructuredData) AddTwitter(name, content string)

AddTwitter adds a Twitter Card tag.

type StructuredDataConfig added in v0.3.0

type StructuredDataConfig struct {
	// Enabled controls whether structured data is generated (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Publisher is the site publisher information for Schema.org
	Publisher *EntityConfig `json:"publisher,omitempty" yaml:"publisher,omitempty" toml:"publisher,omitempty"`

	// DefaultAuthor is the default author for posts without explicit author
	DefaultAuthor *EntityConfig `json:"default_author,omitempty" yaml:"default_author,omitempty" toml:"default_author,omitempty"`
}

StructuredDataConfig configures JSON-LD Schema.org structured data generation.

func NewStructuredDataConfig added in v0.3.0

func NewStructuredDataConfig() StructuredDataConfig

NewStructuredDataConfig creates a new StructuredDataConfig with default values.

func (*StructuredDataConfig) IsEnabled added in v0.3.0

func (s *StructuredDataConfig) IsEnabled() bool

IsEnabled returns whether structured data generation is enabled. Defaults to true if not explicitly set.

type SyndicationConfig

type SyndicationConfig struct {
	// MaxItems is the maximum number of items in syndication feeds
	MaxItems int `json:"max_items" yaml:"max_items" toml:"max_items"`

	// IncludeContent determines if full content is included in feeds
	IncludeContent bool `json:"include_content" yaml:"include_content" toml:"include_content"`
}

SyndicationConfig configures syndication feed behavior.

type TagAggregatorConfig added in v0.7.0

type TagAggregatorConfig struct {
	// Enabled controls whether tag aggregation is active (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Synonyms maps canonical tags to their synonyms/variants.
	// When a post has a synonym tag, it's replaced with the canonical tag.
	// Example: {"kubernetes": ["k8s"], "javascript": ["js"]}
	Synonyms map[string][]string `json:"synonyms,omitempty" yaml:"synonyms,omitempty" toml:"synonyms,omitempty"`

	// Additional maps tags to additional tags that should be automatically added.
	// These are applied recursively to create tag hierarchies.
	// Example: {"pandas": ["data", "python"], "docker": ["containers"]}
	Additional map[string][]string `json:"additional,omitempty" yaml:"additional,omitempty" toml:"additional,omitempty"`

	// GenerateReport controls whether to generate a debug report page (default: false)
	GenerateReport bool `json:"generate_report,omitempty" yaml:"generate_report,omitempty" toml:"generate_report,omitempty"`
}

TagAggregatorConfig configures the tag aggregator plugin for normalizing and expanding tags.

func NewTagAggregatorConfig added in v0.7.0

func NewTagAggregatorConfig() TagAggregatorConfig

NewTagAggregatorConfig creates a new TagAggregatorConfig with default values.

func (*TagAggregatorConfig) IsEnabled added in v0.7.0

func (t *TagAggregatorConfig) IsEnabled() bool

IsEnabled returns whether tag aggregation is enabled. Defaults to true if not explicitly set.

type TagsConfig added in v0.7.0

type TagsConfig struct {
	// Enabled controls whether the tags listing page is generated (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Blacklist is a list of tag names to completely exclude from the tags listing.
	// These tags will not appear on the /tags page and won't be visible publicly.
	// Example: ["draft", "wip", "internal"]
	Blacklist []string `json:"blacklist,omitempty" yaml:"blacklist,omitempty" toml:"blacklist,omitempty"`

	// Private is a list of tag names that exist but should be hidden from the listing.
	// Posts with these tags are still accessible via direct URL, but the tags
	// won't appear on the /tags overview page.
	// Example: ["personal", "unlisted"]
	Private []string `json:"private,omitempty" yaml:"private,omitempty" toml:"private,omitempty"`

	// Title is the title for the tags listing page (default: "Tags")
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Description is the description for the tags listing page
	Description string `json:"description,omitempty" yaml:"description,omitempty" toml:"description,omitempty"`

	// Template is the template file to use (default: "tags.html")
	Template string `json:"template,omitempty" yaml:"template,omitempty" toml:"template,omitempty"`

	// SlugPrefix is the URL prefix for the tags listing (default: "tags")
	SlugPrefix string `json:"slug_prefix,omitempty" yaml:"slug_prefix,omitempty" toml:"slug_prefix,omitempty"`
}

TagsConfig configures the tags listing page at /tags. The tags listing page shows all available tags with post counts and links to tag pages.

func NewTagsConfig added in v0.7.0

func NewTagsConfig() TagsConfig

NewTagsConfig creates a new TagsConfig with default values.

func (*TagsConfig) IsBlacklisted added in v0.7.0

func (t *TagsConfig) IsBlacklisted(tag string) bool

IsBlacklisted returns whether a tag is in the blacklist.

func (*TagsConfig) IsEnabled added in v0.7.0

func (t *TagsConfig) IsEnabled() bool

IsEnabled returns whether the tags listing page is enabled. Defaults to true if not explicitly set.

func (*TagsConfig) IsPrivate added in v0.7.0

func (t *TagsConfig) IsPrivate(tag string) bool

IsPrivate returns whether a tag is in the private list.

type TemplateNotFoundError

type TemplateNotFoundError struct {
	Name       string
	SearchPath string
}

TemplateNotFoundError indicates a template file was not found.

func NewTemplateNotFoundError

func NewTemplateNotFoundError(name, searchPath string) *TemplateNotFoundError

NewTemplateNotFoundError creates a new TemplateNotFoundError.

func (*TemplateNotFoundError) Error

func (e *TemplateNotFoundError) Error() string

type TemplatePreset added in v0.6.0

type TemplatePreset struct {
	// HTML template file for HTML output
	HTML string `json:"html" yaml:"html" toml:"html"`

	// Text template file for txt output
	Text string `json:"txt" yaml:"txt" toml:"txt"`

	// Markdown template file for markdown output
	Markdown string `json:"markdown" yaml:"markdown" toml:"markdown"`

	// OG template file for OpenGraph card output
	OG string `json:"og" yaml:"og" toml:"og"`
}

TemplatePreset defines templates for all output formats. This allows setting all format templates at once with a single preset name.

func (*TemplatePreset) TemplateForFormat added in v0.6.0

func (p *TemplatePreset) TemplateForFormat(format string) string

TemplateForFormat returns the template for a specific format. Returns empty string if the format is not recognized.

type TemplateSyntaxError

type TemplateSyntaxError struct {
	Name    string
	Line    int
	Column  int
	Message string
	Err     error
}

TemplateSyntaxError indicates a syntax error in a template.

func NewTemplateSyntaxError

func NewTemplateSyntaxError(name, message string, err error) *TemplateSyntaxError

NewTemplateSyntaxError creates a new TemplateSyntaxError.

func (*TemplateSyntaxError) Error

func (e *TemplateSyntaxError) Error() string

func (*TemplateSyntaxError) Unwrap

func (e *TemplateSyntaxError) Unwrap() error

type ThemeCalendarConfig added in v0.7.0

type ThemeCalendarConfig struct {
	// Enabled controls whether the theme calendar is active (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Rules is the list of date-based theme rules
	Rules []ThemeCalendarRule `json:"rules,omitempty" yaml:"rules,omitempty" toml:"rules,omitempty"`

	// DefaultPalette is the fallback palette when no rules match (optional)
	// If not set, uses the base theme.palette value
	DefaultPalette string `json:"default_palette,omitempty" yaml:"default_palette,omitempty" toml:"default_palette,omitempty"`
}

ThemeCalendarConfig configures automatic theme switching based on date ranges. This enables seasonal themes, holiday themes, and event-specific styling.

func NewThemeCalendarConfig added in v0.7.0

func NewThemeCalendarConfig() ThemeCalendarConfig

NewThemeCalendarConfig creates a new ThemeCalendarConfig with default values.

func (*ThemeCalendarConfig) IsEnabled added in v0.7.0

func (c *ThemeCalendarConfig) IsEnabled() bool

IsEnabled returns whether the theme calendar is enabled. Defaults to false if not explicitly set.

type ThemeCalendarRule added in v0.7.0

type ThemeCalendarRule struct {
	// Name is a descriptive name for the rule (e.g., "Christmas Season", "Winter Frost")
	Name string `json:"name" yaml:"name" toml:"name"`

	// StartDate is the start of the date range in MM-DD format (e.g., "12-15")
	StartDate string `json:"start_date" yaml:"start_date" toml:"start_date"`

	// EndDate is the end of the date range in MM-DD format (e.g., "12-26")
	// Ranges can cross year boundaries (e.g., start="12-01", end="02-28")
	EndDate string `json:"end_date" yaml:"end_date" toml:"end_date"`

	// Palette overrides theme.palette for this period (optional)
	Palette string `json:"palette,omitempty" yaml:"palette,omitempty" toml:"palette,omitempty"`

	// PaletteLight overrides theme.palette_light for this period (optional)
	PaletteLight string `json:"palette_light,omitempty" yaml:"palette_light,omitempty" toml:"palette_light,omitempty"`

	// PaletteDark overrides theme.palette_dark for this period (optional)
	PaletteDark string `json:"palette_dark,omitempty" yaml:"palette_dark,omitempty" toml:"palette_dark,omitempty"`

	// Background overrides theme.background for this period (optional)
	Background *BackgroundConfig `json:"background,omitempty" yaml:"background,omitempty" toml:"background,omitempty"`

	// Font overrides theme.font for this period (optional)
	Font *FontConfig `json:"font,omitempty" yaml:"font,omitempty" toml:"font,omitempty"`

	// Variables merges with theme.variables for this period (optional)
	// These are deep-merged with the base theme variables
	Variables map[string]string `json:"variables,omitempty" yaml:"variables,omitempty" toml:"variables,omitempty"`

	// CustomCSS overrides theme.custom_css for this period (optional)
	CustomCSS string `json:"custom_css,omitempty" yaml:"custom_css,omitempty" toml:"custom_css,omitempty"`
}

ThemeCalendarRule defines a date range and theme overrides for that period. Rules are matched in order - the first matching rule is applied.

type ThemeConfig

type ThemeConfig struct {
	// Name is the theme name (default: "default")
	Name string `json:"name" yaml:"name" toml:"name"`

	// Palette is the base color palette to use (default: "default-light")
	// When set to a base name like "everforest", the system will auto-detect
	// light/dark variants (e.g., "everforest-light" and "everforest-dark")
	Palette string `json:"palette" yaml:"palette" toml:"palette"`

	// PaletteLight is the palette to use for light mode (optional)
	// If not set, auto-detected from base Palette name
	PaletteLight string `json:"palette_light,omitempty" yaml:"palette_light,omitempty" toml:"palette_light,omitempty"`

	// PaletteDark is the palette to use for dark mode (optional)
	// If not set, auto-detected from base Palette name
	PaletteDark string `json:"palette_dark,omitempty" yaml:"palette_dark,omitempty" toml:"palette_dark,omitempty"`

	// Variables allows overriding specific CSS variables
	Variables map[string]string `json:"variables" yaml:"variables" toml:"variables"`

	// CustomCSS is a path to a custom CSS file to include
	CustomCSS string `json:"custom_css" yaml:"custom_css" toml:"custom_css"`

	// Background configures multi-layered background decorations
	Background BackgroundConfig `json:"background,omitempty" yaml:"background,omitempty" toml:"background,omitempty"`

	// Font configures typography settings
	Font FontConfig `json:"font,omitempty" yaml:"font,omitempty" toml:"font,omitempty"`

	// Switcher configures the multi-palette theme switcher dropdown
	Switcher ThemeSwitcherConfig `json:"switcher,omitempty" yaml:"switcher,omitempty" toml:"switcher,omitempty"`
}

ThemeConfig configures the site theme.

func NewThemeConfig

func NewThemeConfig() ThemeConfig

NewThemeConfig creates a new ThemeConfig with default values.

type ThemeSwitcherConfig added in v0.6.0

type ThemeSwitcherConfig struct {
	// Enabled controls whether the palette switcher is shown (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// IncludeAll includes all discovered palettes in the switcher (default: true)
	// When false, only palettes in the Include list are shown
	IncludeAll *bool `json:"include_all,omitempty" yaml:"include_all,omitempty" toml:"include_all,omitempty"`

	// Include is a list of palette names to include in the switcher
	// Only used when IncludeAll is false
	Include []string `json:"include,omitempty" yaml:"include,omitempty" toml:"include,omitempty"`

	// Exclude is a list of palette names to exclude from the switcher
	// Used when IncludeAll is true
	Exclude []string `json:"exclude,omitempty" yaml:"exclude,omitempty" toml:"exclude,omitempty"`

	// Position controls where the switcher appears: "header", "footer" (default: "header")
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`
}

ThemeSwitcherConfig configures the multi-palette theme switcher dropdown. When enabled, users can select any available palette at runtime in the browser.

func NewThemeSwitcherConfig added in v0.6.0

func NewThemeSwitcherConfig() ThemeSwitcherConfig

NewThemeSwitcherConfig creates a new ThemeSwitcherConfig with default values.

func (*ThemeSwitcherConfig) IsEnabled added in v0.6.0

func (s *ThemeSwitcherConfig) IsEnabled() bool

IsEnabled returns whether the palette switcher is enabled. Defaults to false if not explicitly set.

func (*ThemeSwitcherConfig) IsIncludeAll added in v0.6.0

func (s *ThemeSwitcherConfig) IsIncludeAll() bool

IsIncludeAll returns whether all palettes should be included. Defaults to true if not explicitly set.

type TocConfig added in v0.4.0

type TocConfig struct {
	// Enabled controls whether the TOC is displayed (default: true for docs layout)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// AutoEnable enables automatic TOC display based on content thresholds.
	// When true, TOC will show automatically if min_toc_links or min_word_count
	// thresholds are met, unless explicitly disabled in frontmatter.
	AutoEnable *bool `json:"auto_enable,omitempty" yaml:"auto_enable,omitempty" toml:"auto_enable,omitempty"`

	// MinTocLinks is the minimum number of TOC entries required to auto-show.
	// Only used when AutoEnable is true. Default: 3
	MinTocLinks int `json:"min_toc_links,omitempty" yaml:"min_toc_links,omitempty" toml:"min_toc_links,omitempty"`

	// MinWordCount is the minimum word count required to auto-show.
	// Only used when AutoEnable is true. Default: 500
	MinWordCount int `json:"min_word_count,omitempty" yaml:"min_word_count,omitempty" toml:"min_word_count,omitempty"`

	// Position controls TOC placement: "left" or "right" (default: "right")
	Position string `json:"position,omitempty" yaml:"position,omitempty" toml:"position,omitempty"`

	// Width is the TOC width (default: "220px")
	Width string `json:"width,omitempty" yaml:"width,omitempty" toml:"width,omitempty"`

	// MinDepth is the minimum heading level to include (default: 2)
	MinDepth int `json:"min_depth,omitempty" yaml:"min_depth,omitempty" toml:"min_depth,omitempty"`

	// MaxDepth is the maximum heading level to include (default: 4)
	MaxDepth int `json:"max_depth,omitempty" yaml:"min_depth,omitempty" toml:"max_depth,omitempty"`

	// Title is the TOC section title (default: "On this page")
	Title string `json:"title,omitempty" yaml:"title,omitempty" toml:"title,omitempty"`

	// Collapsible allows the TOC to be collapsed (default: true)
	Collapsible *bool `json:"collapsible,omitempty" yaml:"collapsible,omitempty" toml:"collapsible,omitempty"`

	// DefaultOpen controls if TOC is open by default (default: true)
	DefaultOpen *bool `json:"default_open,omitempty" yaml:"default_open,omitempty" toml:"default_open,omitempty"`

	// ScrollSpy enables highlighting the current section (default: true)
	ScrollSpy *bool `json:"scroll_spy,omitempty" yaml:"scroll_spy,omitempty" toml:"scroll_spy,omitempty"`
}

TocConfig configures the table of contents component.

func NewTocConfig added in v0.4.0

func NewTocConfig() TocConfig

NewTocConfig creates a new TocConfig with default values.

func (t *TocConfig) GetMinTocLinks() int

GetMinTocLinks returns the minimum number of TOC links for auto-show.

func (*TocConfig) GetMinWordCount added in v0.7.0

func (t *TocConfig) GetMinWordCount() int

GetMinWordCount returns the minimum word count for auto-show.

func (*TocConfig) IsAutoEnable added in v0.7.0

func (t *TocConfig) IsAutoEnable() bool

IsAutoEnable returns whether automatic TOC display based on thresholds is enabled.

func (*TocConfig) IsCollapsible added in v0.4.0

func (t *TocConfig) IsCollapsible() bool

IsCollapsible returns whether the TOC can be collapsed.

func (*TocConfig) IsDefaultOpen added in v0.4.0

func (t *TocConfig) IsDefaultOpen() bool

IsDefaultOpen returns whether the TOC is open by default.

func (*TocConfig) IsEnabled added in v0.4.0

func (t *TocConfig) IsEnabled() bool

IsEnabled returns whether the TOC is enabled.

func (*TocConfig) IsScrollSpy added in v0.4.0

func (t *TocConfig) IsScrollSpy() bool

IsScrollSpy returns whether scroll spy is enabled.

func (*TocConfig) ShouldAutoShow added in v0.7.0

func (t *TocConfig) ShouldAutoShow(tocLinkCount, wordCount int) bool

ShouldAutoShow returns true if TOC should automatically show based on content thresholds.

type TwitterTag added in v0.3.0

type TwitterTag struct {
	// Name is the twitter: name (e.g., "twitter:card")
	Name string `json:"name" yaml:"name" toml:"name"`

	// Content is the tag content value
	Content string `json:"content" yaml:"content" toml:"content"`
}

TwitterTag represents a Twitter Card meta tag.

type WebMentionsConfig added in v0.5.0

type WebMentionsConfig struct {
	// Enabled controls whether the webmentions plugin is active (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Outgoing enables sending webmentions for external links (default: true when enabled)
	Outgoing bool `json:"outgoing" yaml:"outgoing" toml:"outgoing"`

	// UserAgent is the User-Agent string for HTTP requests
	UserAgent string `json:"user_agent" yaml:"user_agent" toml:"user_agent"`

	// Timeout is the HTTP request timeout (e.g., "30s")
	Timeout string `json:"timeout" yaml:"timeout" toml:"timeout"`

	// CacheDir is the directory for caching sent webmentions (default: ".cache/webmentions")
	CacheDir string `json:"cache_dir" yaml:"cache_dir" toml:"cache_dir"`

	// ConcurrentRequests is the max number of concurrent webmention requests (default: 5)
	ConcurrentRequests int `json:"concurrent_requests" yaml:"concurrent_requests" toml:"concurrent_requests"`

	// Bridges configures social media bridging for incoming webmentions
	Bridges BridgesConfig `json:"bridges" yaml:"bridges" toml:"bridges"`

	// WebmentionIOToken is the API token for webmention.io (for receiving mentions)
	WebmentionIOToken string `json:"webmention_io_token" yaml:"webmention_io_token" toml:"webmention_io_token"`
}

WebMentionsConfig configures the webmentions plugin for sending outgoing mentions. This is separate from WebmentionConfig which handles receiving mentions.

func NewWebMentionsConfig added in v0.5.0

func NewWebMentionsConfig() WebMentionsConfig

NewWebMentionsConfig creates a new WebMentionsConfig with default values.

type WebPage added in v0.3.0

type WebPage struct {
	Type string `json:"@type"`
	ID   string `json:"@id"`
}

WebPage represents a Schema.org WebPage for JSON-LD.

type WebSite added in v0.3.0

type WebSite struct {
	Context     string       `json:"@context"`
	Type        string       `json:"@type"`
	Name        string       `json:"name"`
	Description string       `json:"description,omitempty"`
	URL         string       `json:"url"`
	Publisher   *SchemaAgent `json:"publisher,omitempty"`
}

WebSite represents a Schema.org WebSite for JSON-LD.

func NewWebSite added in v0.3.0

func NewWebSite(name, url string) *WebSite

NewWebSite creates a new WebSite with required fields.

type WebSubConfig added in v0.7.0

type WebSubConfig struct {
	// Enabled controls whether WebSub discovery links are included (default: false)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// Hubs is the list of WebSub hub URLs to advertise
	Hubs []string `json:"hubs,omitempty" yaml:"hubs,omitempty" toml:"hubs,omitempty"`
}

WebSubConfig configures WebSub discovery links for feeds. See https://www.w3.org/TR/websub/ for the specification.

func NewWebSubConfig added in v0.7.0

func NewWebSubConfig() WebSubConfig

NewWebSubConfig creates a new WebSubConfig with default values.

func (WebSubConfig) HubsList added in v0.7.0

func (w WebSubConfig) HubsList() []string

HubsList returns a copy of configured hub URLs.

func (WebSubConfig) IsEnabled added in v0.7.0

func (w WebSubConfig) IsEnabled() bool

IsEnabled returns whether WebSub discovery links are enabled. Defaults to false if not explicitly set.

type WebmentionConfig added in v0.3.0

type WebmentionConfig struct {
	// Enabled controls whether Webmention link tag is included (default: false)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// Endpoint is the URL of your Webmention endpoint
	// Example: "https://webmention.io/example.com/webmention"
	Endpoint string `json:"endpoint" yaml:"endpoint" toml:"endpoint"`
}

WebmentionConfig configures Webmention endpoint for receiving mentions. Webmention is a simple protocol for notifying URLs when you link to them. See https://www.w3.org/TR/webmention/ for the specification.

func NewWebmentionConfig added in v0.3.0

func NewWebmentionConfig() WebmentionConfig

NewWebmentionConfig creates a new WebmentionConfig with default values.

type WellKnownConfig added in v0.7.0

type WellKnownConfig struct {
	// Enabled controls whether .well-known generation runs (default: true)
	Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty" toml:"enabled,omitempty"`

	// AutoGenerate lists entries to generate from site metadata
	AutoGenerate []string `json:"auto_generate,omitempty" yaml:"auto_generate,omitempty" toml:"auto_generate,omitempty"`

	// SSHFingerprint is written to /.well-known/sshfp if set
	SSHFingerprint string `json:"ssh_fingerprint,omitempty" yaml:"ssh_fingerprint,omitempty" toml:"ssh_fingerprint,omitempty"`

	// KeybaseUsername is written to /.well-known/keybase.txt if set
	KeybaseUsername string `json:"keybase_username,omitempty" yaml:"keybase_username,omitempty" toml:"keybase_username,omitempty"`
}

WellKnownConfig configures auto-generated .well-known entries.

func NewWellKnownConfig added in v0.7.0

func NewWellKnownConfig() WellKnownConfig

NewWellKnownConfig creates a WellKnownConfig with default values.

func (WellKnownConfig) AutoGenerateList added in v0.7.0

func (w WellKnownConfig) AutoGenerateList() []string

AutoGenerateList returns the configured auto-generate list with defaults applied.

func (WellKnownConfig) IsEnabled added in v0.7.0

func (w WellKnownConfig) IsEnabled() bool

IsEnabled returns whether .well-known generation is enabled. Defaults to true if not explicitly set.

type WikilinkHoverConfig added in v0.2.0

type WikilinkHoverConfig struct {
	// Enabled controls whether hover previews are added (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// PreviewLength is the maximum characters for the preview text (default: 200)
	PreviewLength int `json:"preview_length" yaml:"preview_length" toml:"preview_length"`

	// IncludeImage adds data-preview-image attribute if post has a featured image (default: true)
	IncludeImage bool `json:"include_image" yaml:"include_image" toml:"include_image"`

	// ScreenshotService is an optional URL prefix for screenshot generation
	// If set, adds data-preview-screenshot attribute with the URL
	ScreenshotService string `json:"screenshot_service" yaml:"screenshot_service" toml:"screenshot_service"`
}

WikilinkHoverConfig configures the wikilink_hover plugin.

func NewWikilinkHoverConfig added in v0.2.0

func NewWikilinkHoverConfig() WikilinkHoverConfig

NewWikilinkHoverConfig creates a new WikilinkHoverConfig with default values.

type YouTubeConfig added in v0.3.0

type YouTubeConfig struct {
	// Enabled controls whether YouTube URL conversion is active (default: true)
	Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`

	// PrivacyEnhanced uses youtube-nocookie.com for enhanced privacy (default: true)
	PrivacyEnhanced bool `json:"privacy_enhanced" yaml:"privacy_enhanced" toml:"privacy_enhanced"`

	// ContainerClass is the CSS class for the embed container (default: "youtube-embed")
	ContainerClass string `json:"container_class" yaml:"container_class" toml:"container_class"`

	// LazyLoad enables lazy loading of iframe (default: true)
	LazyLoad bool `json:"lazy_load" yaml:"lazy_load" toml:"lazy_load"`
}

YouTubeConfig configures the youtube plugin.

func NewYouTubeConfig added in v0.3.0

func NewYouTubeConfig() YouTubeConfig

NewYouTubeConfig creates a new YouTubeConfig with default values.

Jump to

Keyboard shortcuts

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