config

package
v2.5.0-beta1 Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: MPL-2.0 Imports: 5 Imported by: 0

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.

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.

Option types

GeneratorOption carries options for generator.New and outputter.NewDirectoryWriter, including WithRawOutput, WithDisableTags, WithDisableReadingTime, WithSiteTitle, WithEnvironment, WithCustomData, and WithHTMLPaths. 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

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

type CustomData struct{ Data map[string]any }

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)
	WithHTMLPathsFunc          func(v *HTMLPaths)
}

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 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 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 Option added in v2.0.5

type Option[T any] interface {
	AsOption() T
}

type Port added in v2.1.0

type Port int

Port is the TCP port number the HTTP server listens on.

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

type RendererOption struct {
	WithFuncsFunc func(fm *template.FuncMap)
}

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

Jump to

Keyboard shortcuts

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