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.
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.
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.
Option types ¶
GeneratorOption carries options for generator.New and outputter.NewDirectoryWriter. BaseServerOption carries options for the HTTP server (port, host, middleware). 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 BlogRoot
- type CustomData
- type DisableReadingTime
- type DisableTags
- type Environment
- type EnvironmentConfig
- type GeneratorOption
- func WithBaseOption(baseOption BaseOption) GeneratorOption
- func WithCustomData(data map[string]any) GeneratorOption
- func WithDisableReadingTime() GeneratorOption
- func WithDisableTags() GeneratorOption
- func WithEnvironment(env string) GeneratorOption
- func WithRawOutput() GeneratorOption
- func WithSiteTitle(title string) GeneratorOption
- type Host
- type Option
- type Port
- type RawOutput
- type RendererOption
- type ServerConfig
- type SiteTitle
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseOption ¶ added in v2.1.0
type BaseOption struct {
WithBlogRootFunc func(v *BlogRoot)
}
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().
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/"))
type BaseServerOption ¶ added in v2.1.0
type BaseServerOption struct {
BaseOption
WithPortFunc func(v *Port)
WithHostFunc func(v *Host)
WithMiddlewareFunc func(mw *[]middleware.Middleware)
}
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, and WithMiddleware.
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 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
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 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 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)
}
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(), and WithBaseOption().
func WithBaseOption ¶ 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. Use this when you have a BaseOption (e.g. from WithBlogRoot) and need to supply it alongside other GeneratorOptions.
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 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 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 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 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