Documentation
¶
Overview ¶
Package config provides common configuration options used across the GoBlog generator and outputter packages.
The package implements the functional options pattern for configuration, allowing packages to accept both required positional parameters and optional configuration via option functions.
Functional Options Pattern ¶
Configuration is applied through Option values that can be passed to constructors. Each option function modifies specific configuration fields:
gen := generator.New(postsFS, nil, config.WithRawOutput())
writer := outputter.NewDirectoryWriter("output/", config.WithRawOutput())
Options are implemented as structs containing functions that modify embedded configuration types. This pattern allows for:
- Backward compatibility when adding new options
- Clear, self-documenting API calls
- Optional parameters without function overloading
Available Options ¶
WithRawOutput() enables raw HTML output mode without template wrapping. When enabled in the generator, markdown is converted to HTML without inserting it into page templates. When enabled in the outputter, the tags directory is not created.
WithDisableTags() disables all tag-related output. When enabled, the generator skips rendering tag pages and the tags index, post tag slices are cleared, the outputter skips the tags directory, and the HTTP server does not register /tags routes. Unlike WithRawOutput(), posts and the index page are still rendered with full templates.
WithDisableReadingTime() disables estimated reading time on posts. When enabled, Post.ReadingTimeMinutes is left at zero and the default templates suppress the "· N min read" annotation next to each post date. Reading time is enabled by default (220 WPM, rounded up, 1-minute minimum).
WithSiteTitle(title string) sets the site title used in generated HTML pages and templates.
WithEnvironment(env string) sets the runtime environment ("local", "test", or "production") surfaced to templates via models.BaseData.Environment. Use config.EnvironmentConfig to read the value from the ENVIRONMENT env var.
WithBlogRoot(path string) sets the root path for the blog when deploying at a subdirectory rather than domain root. For example, use "/blog/" when deploying at example.com/blog/. This ensures all generated links in templates use the correct base path. Default is "/" for root deployment.
WithCacheControl(ttl time.Duration) returns a BaseServerOption that sets the Cache-Control max-age TTL on all HTTP responses. When ttl > 0 the server adds "Cache-Control: public, max-age=<N>" to every response. Setting ttl to 0 or any non-positive value disables the header. The default is one hour.
WithLogger(l *slog.Logger) is a BaseOption that sets the structured logger used by the receiving component. It flows into every constructor that accepts BaseOption values (generator.New via GeneratorOption, server.New via BaseServerOption, outputter.NewDirectoryWriter via GeneratorOption) and into watcher.New via WatcherOption (which embeds BaseOption). When not supplied, each constructor falls back to slog.Default() at construction time. Passing nil has the same effect as omitting the option.
WithFuncs(funcs template.FuncMap) is a RendererOption that registers additional template functions for use in all templates. Functions are merged into the built-in FuncMap (formatDate, shortDate, year). A function whose name matches a built-in silently replaces it. Pass RendererOption values to generator.NewTemplateRenderer, or to ServerConfig.RendererOpts for the HTTP server path.
WithHTMLPaths() is a GeneratorOption that switches BaseData.Path values to use .html file extensions instead of clean URLs. When enabled, the index path becomes /index.html (or /<root>.html for a non-root BlogRoot), and all other pages get .html appended. This is automatically applied by the goblog generate CLI so canonical URLs in static output match the actual files on disk. Library users serving via pkg/server should leave this off; the server accepts both clean URLs and .html URLs automatically.
WithCustomData(data map[string]any) is a GeneratorOption that merges arbitrary key-value data into models.BaseData.Custom, making it accessible in all templates as {{.Custom.key}}. Multiple calls merge their maps, with later values overwriting earlier ones for duplicate keys. The field is nil when no WithCustomData option is supplied.
WithHealthChecks() is a BaseServerOption that enables health-check endpoints on the HTTP server. When enabled, GET /healthz/live always returns 200 OK, while GET /healthz/ready and GET /healthz/startup return 200 OK once posts and templates have loaded and 503 Service Unavailable while starting up or after a load failure. The endpoints require no authentication and are served before the middleware stack. The server binds the HTTP listener before initialising content so probes can observe the startup state. Health checks are disabled by default; the Docker image enables them via --health-checks.
Option types ¶
GeneratorOption carries options for generator.New and outputter.NewDirectoryWriter, including WithRawOutput, WithDisableTags, WithDisableReadingTime, WithSiteTitle, WithEnvironment, WithCustomData, WithHTMLPaths, and (via the embedded BaseOption) WithLogger and WithBlogRoot. BaseServerOption carries options for the HTTP server (port, host, middleware, cache-control TTL, health-check endpoints, and via the embedded BaseOption: WithLogger, WithBlogRoot). WatcherOption carries options for watcher.New (debounce, and via the embedded BaseOption: WithLogger, WithBlogRoot). RendererOption carries options for generator.NewTemplateRenderer (custom funcs). ServerConfig groups all three option types plus a TemplateDir filesystem for the server constructor (server.New).
Usage Examples ¶
Basic usage with a single option:
fsys := os.DirFS("posts/")
gen := generator.New(fsys, nil, config.WithRawOutput())
Multiple options can be combined:
renderer, _ := generator.NewTemplateRenderer(templates.Default)
gen := generator.New(fsys, renderer,
config.WithRawOutput(),
config.WithSiteTitle("My Blog"),
)
Registering a custom template function:
renderer, _ := generator.NewTemplateRenderer(
templates.Default,
config.WithFuncs(template.FuncMap{"upper": strings.ToUpper}),
)
Injecting custom data into templates:
gen := generator.New(fsys, renderer,
config.WithCustomData(map[string]any{
"author": "Jane Smith",
}),
)
Configuring blog root for subdirectory deployment:
renderer, _ := generator.NewTemplateRenderer(templates.Default)
gen := generator.New(fsys, renderer,
config.WithBlogRoot("/blog/"),
)
Concurrency ¶
Option values are safe to create and use concurrently. Configuration structs are safe to read concurrently once created, but should not be modified after construction.
Index ¶
- type BaseOption
- type BaseServerOption
- type BaseURL
- type BlogRoot
- type CacheControlTTL
- type CustomData
- type DisableFeeds
- type DisableReadingTime
- type DisableTags
- type Environment
- type EnvironmentConfig
- type FeedPostLimit
- type GeneratorOption
- func WithBaseOption(baseOption BaseOption) GeneratorOptiondeprecated
- func WithBaseURL(url string) GeneratorOption
- func WithCustomData(data map[string]any) GeneratorOption
- func WithDisableFeeds() GeneratorOption
- func WithDisableReadingTime() GeneratorOption
- func WithDisableTags() GeneratorOption
- func WithEnvironment(env string) GeneratorOption
- func WithFeedPostLimit(limit int) GeneratorOption
- func WithHTMLPaths() GeneratorOption
- func WithRawOutput() GeneratorOption
- func WithSiteTitle(title string) GeneratorOption
- type HTMLPaths
- type HealthChecks
- type Host
- type Logger
- type Option
- type Port
- type RawOutput
- type RendererOption
- type ServerConfig
- type SiteTitle
- type WatcherDebounce
- type WatcherOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseOption ¶ added in v2.1.0
BaseOption represents a configuration option that can be applied to many different instances during construction.
Options use the functional options pattern, where each option function returns an BaseOption struct containing one or more function pointers that modify specific configuration fields.
This type should not be constructed directly by users. Instead, use the provided option functions like WithBlogRoot() or WithLogger().
func WithBlogRoot ¶ added in v2.1.0
func WithBlogRoot(root string) BaseOption
WithBlogRoot returns an Option that sets the blog's root path.
The blog root is used in generated HTML pages and templates.
Example usage:
gen := generator.New(fsys, renderer, config.WithBlogRoot("/blog/"))
func WithLogger ¶ added in v2.5.0
func WithLogger(l *slog.Logger) BaseOption
WithLogger returns a BaseOption that sets the structured logger used by the component.
Passing nil is permitted and is treated the same as not supplying the option: the component falls back to log/slog.Default at construction time.
Example usage:
import "log/slog"
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
gen := generator.New(fsys, renderer, config.WithLogger(logger).AsGeneratorOption())
w, err := watcher.New("posts/", config.WithLogger(logger))
writer := outputter.NewDirectoryWriter("output/", config.WithLogger(logger).AsGeneratorOption())
func (BaseOption) AsGeneratorOption ¶ added in v2.5.0
func (o BaseOption) AsGeneratorOption() GeneratorOption
AsGeneratorOption returns a GeneratorOption that applies this BaseOption to a generator or outputter instance, enabling a BaseOption (e.g. from WithLogger or WithBlogRoot) to be passed to generator constructors alongside other GeneratorOptions.
func (BaseOption) AsServerOption ¶ added in v2.5.0
func (o BaseOption) AsServerOption() BaseServerOption
AsServerOption returns a BaseServerOption that applies this BaseOption to a server instance, enabling a BaseOption (e.g. from WithLogger or WithBlogRoot) to be passed to server constructors alongside other server options.
func (BaseOption) AsWatcherOption ¶ added in v2.5.0
func (o BaseOption) AsWatcherOption() WatcherOption
AsWatcherOption returns a WatcherOption that applies this BaseOption to a watcher instance, enabling a BaseOption (e.g. from WithLogger) to be passed to watcher constructors alongside other WatcherOptions.
type BaseServerOption ¶ added in v2.1.0
type BaseServerOption struct {
BaseOption
WithPortFunc func(v *Port)
WithHostFunc func(v *Host)
WithMiddlewareFunc func(mw *[]middleware.Middleware)
WithCacheControlFunc func(v *CacheControlTTL)
WithHealthChecksFunc func(v *HealthChecks)
}
BaseServerOption represents a configuration option for the HTTP server. Options use the functional options pattern; each value carries a function pointer that modifies a specific server setting.
This type should not be constructed directly. Use the provided option functions: WithPort, WithHost, WithMiddleware, WithCacheControl, WithHealthChecks, or call BaseOption.AsServerOption on a BaseOption value (e.g. from WithLogger).
func WithCacheControl ¶
func WithCacheControl(ttl time.Duration) BaseServerOption
WithCacheControl returns a BaseServerOption that sets the Cache-Control max-age TTL on all HTTP responses served by the server.
When ttl > 0 the server adds "Cache-Control: public, max-age=<N>" to every response, where N is ttl truncated to whole seconds. Setting ttl to 0 (or any non-positive value) disables the header so no Cache-Control is sent.
The default (when this option is not supplied) is one hour.
Example usage:
cfg := config.ServerConfig{
Server: []config.BaseServerOption{
config.WithCacheControl(24 * time.Hour), // cache for one day
},
}
To disable caching entirely:
cfg.Server = append(cfg.Server, config.WithCacheControl(0))
func WithHealthChecks ¶
func WithHealthChecks() BaseServerOption
WithHealthChecks returns a BaseServerOption that enables health-check endpoints on the HTTP server.
When enabled, the server exposes three unauthenticated endpoints:
- GET /healthz/live — always 200 OK (process is alive)
- GET /healthz/ready — 200 OK once posts and templates have loaded; 503 Service Unavailable while starting up or if loading failed
- GET /healthz/startup — same semantics as /healthz/ready
The server binds the HTTP listener before initialising content when health checks are enabled, allowing probes to observe the startup state. Response bodies are plain text ("ok" or an error description).
Health checks are disabled by default.
Example usage:
cfg := config.ServerConfig{
Server: []config.BaseServerOption{
config.WithHealthChecks(),
},
}
func WithHost ¶ added in v2.1.0
func WithHost(host string) BaseServerOption
WithHost returns a BaseServerOption that sets the HTTP server bind address.
Example usage:
cfg := config.ServerConfig{
Server: []config.BaseServerOption{
config.WithHost("127.0.0.1"),
},
}
func WithMiddleware ¶ added in v2.1.0
func WithMiddleware(mw ...middleware.Middleware) BaseServerOption
WithMiddleware returns a BaseServerOption that adds HTTP middleware to the server.
Middleware are applied in the order provided. The first middleware in the list will be the outermost wrapper (executed first for requests, last for responses). Multiple calls to WithMiddleware append to the middleware chain.
Example usage:
import (
"github.com/harrydayexe/GoWebUtilities/logging"
"github.com/harrydayexe/GoWebUtilities/middleware"
)
cfg := config.ServerConfig{
Server: []config.BaseServerOption{
config.WithPort(8080),
config.WithMiddleware(
logging.New(logger), // Built-in logging
customAuthMiddleware, // Custom middleware
),
},
}
All middleware must be safe for concurrent use by multiple goroutines.
func WithPort ¶ added in v2.1.0
func WithPort(port int) BaseServerOption
WithPort returns a BaseServerOption that sets the HTTP server listen port.
Example usage:
cfg := config.ServerConfig{
Server: []config.BaseServerOption{
config.WithPort(8080),
},
}
type BaseURL ¶
type BaseURL string
BaseURL is a configuration type that holds the absolute base URL of the site (e.g. "https://example.com").
BaseURL must contain only the scheme and host — do not include a path. If the blog is deployed under a sub-path (e.g. "https://example.com/blog"), use WithBlogRoot for the path portion; it is appended automatically when building feed URLs. Including a path in BaseURL produces duplicated path segments (e.g. "…/blog/blog/posts/…").
BaseURL is required for feed generation: RSS and Atom items must reference fully-qualified URLs. When BaseURL is empty, the generator skips feed generation and emits an info log. HTML page generation is not affected.
This type is typically embedded in generator configuration structs and should be set using the WithBaseURL option function.
func (BaseURL) AsOption ¶
func (o BaseURL) AsOption() GeneratorOption
AsOption returns a GeneratorOption that re-applies this BaseURL value to another component.
type BlogRoot ¶ added in v2.1.0
type BlogRoot string
BlogRoot is a configuration type that holds the blog's root path
This type is typically embedded in generator configuration structs and should be set using the WithBlogRoot() option function.
func (BlogRoot) AsOption ¶ added in v2.1.0
func (o BlogRoot) AsOption() BaseOption
AsOption returns a BaseOption that re-applies this BlogRoot value to another component, enabling a resolved blog root to be forwarded to sub-components without reaching into its underlying string.
type CacheControlTTL ¶
CacheControlTTL holds the max-age duration for the Cache-Control response header. When TTL is greater than zero the server adds "Cache-Control: public, max-age=<seconds>" to every response, telling browsers and shared caches how long they may serve the response without revalidating. A TTL of zero or negative disables the header entirely.
The default TTL (applied when no WithCacheControl option is supplied) is one hour.
type CustomData ¶ added in v2.4.0
CustomData is a configuration type that holds arbitrary key-value data surfaced to all page templates via github.com/harrydayexe/GoBlog/v2/pkg/models.BaseData.Custom.
This type is typically embedded in generator configuration structs and should be set using the WithCustomData option function.
func (CustomData) AsOption ¶ added in v2.4.0
func (o CustomData) AsOption() GeneratorOption
AsOption converts this CustomData value back into a GeneratorOption so it can be passed to generator and server constructors that accept GeneratorOption values (e.g. when round-tripping through a ServerConfig).
type DisableFeeds ¶
type DisableFeeds struct{ Disable bool }
DisableFeeds is a configuration type that controls whether RSS and Atom feeds are generated.
When Disable is true:
- The generator skips all feed generation even if a BaseURL is configured
- GeneratedBlog feed fields are left empty
- The outputter writes no feed files
- BaseData.FeedsEnabled is set to false for all templates
This type is typically embedded in generator and outputter configuration structs and should be set using the WithDisableFeeds option function.
func (DisableFeeds) AsOption ¶
func (o DisableFeeds) AsOption() GeneratorOption
AsOption converts this DisableFeeds value back into a GeneratorOption.
type DisableReadingTime ¶ added in v2.3.0
type DisableReadingTime struct{ Disable bool }
DisableReadingTime is a configuration type that controls whether estimated reading times are computed and surfaced on post pages.
When Disable is true:
- Post.ReadingTimeMinutes is left at zero for all posts
- The default templates omit the "· N min read" annotation next to the date
This type is typically embedded in generator configuration structs and should be set using the WithDisableReadingTime() option function.
func (DisableReadingTime) AsOption ¶ added in v2.3.0
func (o DisableReadingTime) AsOption() GeneratorOption
type DisableTags ¶ added in v2.3.0
type DisableTags struct{ Disable bool }
DisableTags is a configuration type that controls whether tag pages are generated and served.
When Disable is true:
- The generator skips rendering individual tag pages and the tags index
- Post.Tags slices are cleared in the assembled blog so the default templates do not render tag pills
- The outputter skips creating the tags directory
- The HTTP server skips registering /tags routes
- BaseData.TagsEnabled is set to false for all templates
This type is typically embedded in generator, outputter, and server configuration structs and should be set using the WithDisableTags() option function.
func (DisableTags) AsOption ¶ added in v2.3.0
func (o DisableTags) AsOption() GeneratorOption
type Environment ¶ added in v2.1.2
type Environment struct{ Environment string }
Environment is a configuration type holding the runtime environment name (e.g. "local", "test", "production"). It is exposed to templates via models.BaseData.Environment so users can branch on environment.
func (Environment) AsOption ¶ added in v2.1.2
func (o Environment) AsOption() GeneratorOption
type EnvironmentConfig ¶ added in v2.1.2
type EnvironmentConfig struct {
// Environment is read from the ENVIRONMENT env var. Valid values are
// "local" (default), "test", and "production".
Environment gwucfg.Environment `env:"ENVIRONMENT" envDefault:"local"`
}
EnvironmentConfig reads the runtime environment from the ENVIRONMENT env var via gowebutilities config.ParseConfig. Only the Environment field is parsed, so it does not conflict with the CLI-flag-driven port/timeout settings.
func (EnvironmentConfig) Validate ¶ added in v2.1.2
func (c EnvironmentConfig) Validate() error
Validate ensures Environment is one of the gowebutilities-defined constants.
type FeedPostLimit ¶
type FeedPostLimit struct{ Limit int }
FeedPostLimit is a configuration type that controls the maximum number of posts included in each generated feed.
The limit applies to both the site-wide feed and every per-tag feed. Posts are selected in reverse-chronological order (newest first), so a limit of 10 means only the 10 most recent posts appear in each feed.
A zero or negative value means no limit: all posts are included. When unset the library applies no limit; the goblog CLI defaults to 10.
This type is typically embedded in generator configuration structs and should be set using the WithFeedPostLimit option function.
func (FeedPostLimit) AsOption ¶
func (o FeedPostLimit) AsOption() GeneratorOption
AsOption converts this FeedPostLimit value back into a GeneratorOption.
type GeneratorOption ¶ added in v2.1.0
type GeneratorOption struct {
BaseOption
WithRawOutputFunc func(v *RawOutput)
WithDisableTagsFunc func(v *DisableTags)
WithDisableReadingTimeFunc func(v *DisableReadingTime)
WithSiteTitleFunc func(v *SiteTitle)
WithEnvironmentFunc func(v *Environment)
WithCustomDataFunc func(v *CustomData)
WithHTMLPathsFunc func(v *HTMLPaths)
WithBaseURLFunc func(v *BaseURL)
WithDisableFeedsFunc func(v *DisableFeeds)
WithFeedPostLimitFunc func(v *FeedPostLimit)
}
GeneratorOption represents a configuration option that can be applied to generator or outputter instances during construction.
Options use the functional options pattern, where each option function returns an GeneratorOption struct containing one or more function pointers that modify specific configuration fields.
This type should not be constructed directly by users. Instead, use the provided option functions like WithRawOutput(), WithDisableTags(), WithDisableReadingTime(), WithSiteTitle(), WithEnvironment(), WithCustomData(), WithBaseURL(), WithDisableFeeds(), WithFeedPostLimit(), or call BaseOption.AsGeneratorOption on a BaseOption value.
func WithBaseOption
deprecated
added in
v2.1.0
func WithBaseOption(baseOption BaseOption) GeneratorOption
WithBaseOption wraps a BaseOption as a GeneratorOption so it can be passed to generator constructors that accept GeneratorOption values.
Deprecated: call BaseOption.AsGeneratorOption directly instead.
func WithBaseURL ¶
func WithBaseURL(url string) GeneratorOption
WithBaseURL returns a GeneratorOption that sets the site's absolute base URL.
The base URL is prepended to site-relative paths to produce fully-qualified URLs for RSS/Atom feed items. It must contain only the scheme and host (e.g. "https://example.com"). If the blog lives under a sub-path, configure that via WithBlogRoot — including the path in the base URL produces duplicated path segments in every feed URL.
Trailing slashes are trimmed before the base URL is used, so "https://example.com/" and "https://example.com" are equivalent.
When no base URL is configured, feed generation is silently skipped (see WithDisableFeeds to explicitly opt out instead).
Example usage:
gen := generator.New(fsys, renderer, config.WithBaseURL("https://example.com"))
func WithCustomData ¶ added in v2.4.0
func WithCustomData(data map[string]any) GeneratorOption
WithCustomData returns a GeneratorOption that merges the supplied map into the custom data available to all page templates as {{ .Custom.key }}.
The map is exposed on github.com/harrydayexe/GoBlog/v2/pkg/models.BaseData.Custom and is available in every rendered page: post, index, tag, and tags-index.
Multiple calls to WithCustomData accumulate: keys are merged in the order the options are applied, with later values overwriting earlier ones for the same key. Templates should guard access with {{ with .Custom }} or {{ if .Custom }} when the field may be nil (i.e. when no WithCustomData option was supplied).
The same map instance is shared across all pages rendered in a single Generate call. Callers must not mutate the map after passing it to WithCustomData. Values stored in the map must be safe for concurrent reads because the HTTP server may render multiple pages in parallel.
Security ¶
Store only plain, immutable values (strings, numbers, booleans) in the map. Do not pre-wrap values in html/template.HTML, html/template.JS, html/template.JSStr, html/template.URL, html/template.CSS, or html/template.HTMLAttr: those types signal to html/template that the value is already safe and bypass contextual auto-escaping, creating an XSS sink if the value originates from user-controlled input. Let html/template escape values at render time instead.
Do not construct custom data from untrusted input at request time. This map is intended for static, developer-controlled values only.
Example usage:
gen := generator.New(fsys, renderer,
config.WithCustomData(map[string]any{
"author": "Jane Smith",
"analyticsID": "UA-12345",
}),
)
In a template:
{{ with .Custom }}
<meta name="author" content="{{ .author }}">
{{ end }}
func WithDisableFeeds ¶
func WithDisableFeeds() GeneratorOption
WithDisableFeeds returns a GeneratorOption that disables all feed generation.
By default, GoBlog generates RSS 2.0 and Atom feeds when a base URL is configured via WithBaseURL. Applying this option suppresses that behaviour entirely, regardless of whether a base URL is set.
When applied to the outputter, no feed files are written. Templates receive BaseData.FeedsEnabled = false and will suppress any feed discovery links and visible RSS navigation.
Example usage:
gen := generator.New(fsys, renderer, config.WithDisableFeeds())
writer := outputter.NewDirectoryWriter("output/", config.WithDisableFeeds())
func WithDisableReadingTime ¶ added in v2.3.0
func WithDisableReadingTime() GeneratorOption
WithDisableReadingTime returns a GeneratorOption that disables reading time estimation on posts.
When applied to a generator, Post.ReadingTimeMinutes will remain zero for all posts. The default templates guard the "· N min read" annotation with {{if .Post.ReadingTimeMinutes}}, so setting this option suppresses the display without requiring template changes.
Example usage:
gen := generator.New(fsys, renderer, config.WithDisableReadingTime())
func WithDisableTags ¶ added in v2.3.0
func WithDisableTags() GeneratorOption
WithDisableTags returns a GeneratorOption that disables all tag-related output.
When applied to a generator, it will skip rendering tag pages and the tags index. Post tag slices are cleared so that the default templates do not render per-post tag pills. When applied to an outputter, it will skip creating the tags directory. When applied to the HTTP server, /tags routes are not registered.
Example usage:
gen := generator.New(fsys, renderer, config.WithDisableTags())
writer := outputter.NewDirectoryWriter("output/", config.WithDisableTags())
func WithEnvironment ¶ added in v2.1.2
func WithEnvironment(env string) GeneratorOption
WithEnvironment returns a GeneratorOption that sets the runtime environment surfaced to all page templates via models.BaseData.Environment. Callers are responsible for supplying a validated value (e.g. via gowebutilities config.ParseConfig with EnvironmentConfig).
Example usage:
gen := generator.New(fsys, renderer, config.WithEnvironment("production"))
func WithFeedPostLimit ¶
func WithFeedPostLimit(limit int) GeneratorOption
WithFeedPostLimit returns a GeneratorOption that sets the maximum number of posts included in each generated feed.
A value of 0 or any negative number means unlimited — all posts are included. The same limit applies to the site-wide feed and every per-tag feed. When this option is not set, the library applies no limit (the goblog CLI uses a default of 10).
Example usage:
gen := generator.New(fsys, renderer,
config.WithBaseURL("https://example.com"),
config.WithFeedPostLimit(20),
)
func WithHTMLPaths ¶ added in v2.4.0
func WithHTMLPaths() GeneratorOption
WithHTMLPaths returns a GeneratorOption that switches BaseData.Path to use .html-suffixed file paths instead of clean URLs.
This is automatically applied by the goblog generate CLI so that canonical URLs in static output match the actual .html files written to disk. Library users serving content via pkg/server should leave this option off; the server accepts both clean URLs and .html URLs via its built-in StripHTMLExtension middleware.
Path values with this option enabled:
BlogRoot = "/" BlogRoot = "/blog/" Index: /index.html /blog.html Post: /posts/slug.html /blog/posts/slug.html Tag: /tags/go.html /blog/tags/go.html TagsIdx: /tags.html /blog/tags.html
Example usage:
gen := generator.New(fsys, renderer, config.WithHTMLPaths())
func WithRawOutput ¶
func WithRawOutput() GeneratorOption
WithRawOutput returns an Option that enables raw HTML output mode.
When this option is applied to a generator, it will produce HTML content without template wrapping - only the Markdown-to-HTML conversion is performed. When applied to an outputter, it will skip creating the tags directory.
This is useful for scenarios where you want to integrate GoBlog's HTML output into your own templates or existing site structure.
Example usage:
gen := generator.New(fsys, nil, config.WithRawOutput())
writer := outputter.NewDirectoryWriter("output/", config.WithRawOutput())
When using WithRawOutput on the generator, no template renderer is needed because templates are bypassed entirely; pass nil as the renderer.
func WithSiteTitle ¶ added in v2.0.5
func WithSiteTitle(title string) GeneratorOption
WithSiteTitle returns an Option that sets the site title.
The site title is used in generated HTML pages and templates.
Example usage:
gen := generator.New(fsys, renderer, config.WithSiteTitle("My Blog"))
type HTMLPaths ¶ added in v2.4.0
type HTMLPaths struct{ Enable bool }
HTMLPaths is a configuration type that controls whether BaseData.Path values are emitted with a .html file extension.
When Enable is true:
- Index page path becomes /index.html (BlogRoot "/") or /<root>.html (other roots)
- Post, tag, and tags-index paths have .html appended
This type is typically embedded in generator configuration structs and should be set using the WithHTMLPaths() option function.
func (HTMLPaths) AsOption ¶ added in v2.4.0
func (o HTMLPaths) AsOption() GeneratorOption
AsOption converts this HTMLPaths value back into a GeneratorOption.
type HealthChecks ¶
type HealthChecks struct{ Enabled bool }
HealthChecks is a configuration type that controls whether the HTTP server exposes health-check endpoints at /healthz/live, /healthz/ready, and /healthz/startup.
When Enabled is true, the server binds the HTTP listener before loading posts and templates, so liveness/readiness/startup probes can reach the endpoints during startup. Health checks are disabled by default; the Docker image enables them via the --health-checks flag.
This type is typically embedded in the server struct and set via WithHealthChecks.
type Host ¶ added in v2.1.0
type Host string
Host is the network address the HTTP server binds to. An empty Host binds to all available network interfaces.
type Logger ¶ added in v2.5.0
Logger is a configuration type that holds a log/slog.Logger for structured logging.
This type is typically embedded in constructor configuration structs and should be set using the WithLogger option function. When no logger is supplied, constructors fall back to log/slog.Default at construction time.
func (Logger) AsOption ¶ added in v2.5.0
func (o Logger) AsOption() BaseOption
AsOption returns a BaseOption that re-applies this Logger value to another component, enabling a resolved logger to be forwarded to sub-components without reaching into its underlying log/slog.Logger.
type Option ¶ added in v2.0.5
type Option[T any] interface { AsOption() T }
Option is implemented by resolved configuration value types that can convert themselves back into a functional option of type T.
This allows a value that has already been applied to one component to be forwarded to another without unpacking its underlying fields. For example, BlogRoot and Logger both implement Option[BaseOption], so a server can forward its resolved BlogRoot or Logger to a sub-component by calling AsOption() rather than constructing a new option from scratch.
type RawOutput ¶ added in v2.0.5
type RawOutput struct{ RawOutput bool }
RawOutput is a configuration type that controls whether HTML output is generated with or without template wrapping.
When RawOutput is true:
- The generator produces only Markdown-to-HTML conversion without templates
- The outputter skips creating the tags directory
- Individual post files contain raw HTML fragments
This type is typically embedded in generator and outputter configuration structs and should be set using the WithRawOutput() option function.
func (RawOutput) AsOption ¶ added in v2.1.0
func (o RawOutput) AsOption() GeneratorOption
type RendererOption ¶ added in v2.4.0
RendererOption represents a configuration option that can be applied to a github.com/harrydayexe/GoBlog/v2/pkg/generator.TemplateRenderer during construction via github.com/harrydayexe/GoBlog/v2/pkg/generator.NewTemplateRenderer.
Options use the functional options pattern: each value carries a function pointer that modifies a specific renderer setting.
This type should not be constructed directly. Use the provided option functions such as WithFuncs.
func WithFuncs ¶ added in v2.4.0
func WithFuncs(funcs template.FuncMap) RendererOption
WithFuncs returns a RendererOption that merges the supplied functions into the template FuncMap used by github.com/harrydayexe/GoBlog/v2/pkg/generator.NewTemplateRenderer.
The built-in helpers available to all templates are:
formatDate(t time.Time) string formats t as "January 2, 2006" shortDate(t time.Time) string formats t as "Jan 2, 2006" year() int returns the current calendar year
If a key in funcs matches one of those built-in names, the supplied function replaces the built-in and a warning is logged via slog. This allows intentional overrides (for example, substituting your own date format), but will also suppress default template behaviour if done accidentally. Check against the list above before registering a function to avoid unintentional collisions.
Multiple calls to WithFuncs accumulate: functions are merged in the order the options are applied, with later registrations overwriting earlier ones for the same key.
Security ¶
html/template's contextual auto-escaping is bypassed for any function that returns one of the following pre-sanitised types: html/template.HTML, html/template.JS, html/template.JSStr, html/template.URL, html/template.CSS, or html/template.HTMLAttr. Never use those return types with values derived from user-controlled input, as doing so opts the value out of escaping and creates an XSS sink.
Example usage:
import (
"strings"
"html/template"
"github.com/harrydayexe/GoBlog/v2/pkg/config"
"github.com/harrydayexe/GoBlog/v2/pkg/generator"
"github.com/harrydayexe/GoBlog/v2/pkg/templates"
)
renderer, err := generator.NewTemplateRenderer(
templates.Default,
config.WithFuncs(template.FuncMap{
"upper": strings.ToUpper,
}),
)
type ServerConfig ¶ added in v2.1.0
type ServerConfig struct {
Server []BaseServerOption
Gen []GeneratorOption
TemplateDir fs.FS
RendererOpts []RendererOption
}
ServerConfig is the top-level configuration for the HTTP server.
Server holds server-level options (port, host, middleware). Gen holds generator-level options (site title, environment, custom data, etc.). TemplateDir overrides the template filesystem; when nil the built-in templates are used. RendererOpts holds renderer-level options (custom template functions) and is forwarded to the internal github.com/harrydayexe/GoBlog/v2/pkg/generator.NewTemplateRenderer call so users of the server API can register custom FuncMap entries without constructing a renderer manually.
type SiteTitle ¶ added in v2.0.5
type SiteTitle struct{ SiteTitle string }
SiteTitle is a configuration type that holds the site's title.
This type is typically embedded in generator configuration structs and should be set using the WithSiteTitle() option function.
func (SiteTitle) AsOption ¶ added in v2.1.0
func (o SiteTitle) AsOption() GeneratorOption
type WatcherDebounce ¶ added in v2.5.0
WatcherDebounce holds the event debounce duration for the watcher. Events that arrive within this window are coalesced into a single callback invocation.
type WatcherOption ¶ added in v2.5.0
type WatcherOption struct {
BaseOption
WithDebounceFunc func(v *WatcherDebounce)
}
WatcherOption represents a configuration option for a filesystem Watcher. Options use the functional options pattern; each value carries a function pointer that modifies a specific watcher setting.
This type should not be constructed directly. Use the provided option functions: WithDebounce, or call BaseOption.AsWatcherOption on a BaseOption value (e.g. from WithLogger).
func WithDebounce ¶ added in v2.5.0
func WithDebounce(d time.Duration) WatcherOption
WithDebounce returns a WatcherOption that sets the event debounce window. File-system events that arrive within this duration of each other are coalesced into a single onChange invocation. Defaults to 300ms.
Example usage:
w, err := watcher.New("posts/", config.WithDebounce(500*time.Millisecond))