Hwaro::Models::Config
Constants
Section keys read as an array of tables ([[taxonomies]]). Every
other registered section key is a table, except the two below.
[menus] auto_sections = "<menu>" — a setting, not a menu name.
Sections whose loader also accepts a boolean: sitemap = true is the
pre-table form load_sitemap still honours for backward compatibility.
Every top-level key load reads (scalars + registered section keys).
Used to warn on unrecognized keys instead of silently ignoring them —
a typo'd [markdonw] or titel = otherwise disables a feature with
zero feedback. Templates cannot read arbitrary raw config keys (the
site/config objects expose structured fields only), so an unknown
top-level key is always dead configuration. Sorted, so "did you mean"
suggestions tie-break the same way regardless of load order.
Basenames that do not name a file. Every generated-file emitter
(sitemap, robots, search, feeds, llms) writes to
Path[output_dir, File.basename(configured_filename)], and
File.basename maps each of these back to itself — so the write target
collapses onto the output DIRECTORY instead of a file inside it. The
atomic writer then tries to rename its temp file onto a directory and
the build dies with a raw IO::Error naming an internal
.<pid>.<fiber>.tmp path under exit 70, the code this project reserves
for internal bugs.
The four scalar keys load reads directly, ahead of any section.
Sections whose loader validates the shape itself: [versions] takes a
table or a bare [[versions]] array and raises a config error for
anything else, so "Ignoring" would be wrong.
[versions] (switches) + [[versions.list]] (entries). TOML cannot
make one key both a table and an array of tables, so a bare
[[versions]] array is accepted too: entries only, default switches.
Validation is strict — a misconfigured version silently publishing docs at the wrong URL is worse than a failed build:
namerequired, URL-safe, uniquepath(defaults to name) content-relative, unique, non-nested- exactly one
latest = true(none → the first entry is latest) - search / feeds / taxonomies ∈ {"latest", "all"}
Constructors
Class methods
Load and parse a config.toml into a populated Config.
Raises Hwaro::HwaroError(HWARO_E_CONFIG) directly at the source for
file-not-found and TOML parse errors so every caller (build, deploy,
doctor, tool, services) gets a classified error with exit code 3
without having to do substring matching on the exception message.
File-not-found is classified as HWARO_E_CONFIG rather than HWARO_E_IO
because a missing config.toml is a config-level user error, not an
arbitrary IO failure.
Accepts an absolute http(s)://host[:port][/path] URL or the empty
string (which means "no absolute URL is configured"). Raises
ArgumentError on anything else so callers can wrap the failure in
whichever classified HwaroError code suits their context
(HWARO_E_CONFIG for config.toml, HWARO_E_USAGE for CLI flags).
Instance methods
Path component of base_url, used to make root-relative links work when
the site is deployed under a subpath (e.g. GitHub/GitLab project pages
served at https://user.github.io/repo/). For https://x.com/repo this
returns /repo; for a domain-root deployment (https://x.com) or an
empty base_url it returns "". Trailing slashes are stripped so callers
can build base_path + page.url without producing //.
Normalize on assignment: a trailing slash makes {{ base_url }}/path
templates (and canonical/og URLs) emit //. Strip it so the build is
correct whether the trailing slash came from config.toml or --base-url
(previously only doctor --fix normalized this).
Get language config by code, returns nil if not found
Check if site is multilingual. Memoized — this runs several times
per page during render, and the languages table only mutates during
config load, before the first call. The languages= /
default_language= setters invalidate; in-place mutation of the
languages Hash after the first call would not (don't do that).
A build needs a real base_url: refuse one still naming an unset
variable unless the command line supplies its own (--base-url, or
the localhost URL serve always passes).
True when built-in Sass compilation is on and relative_path is an
SCSS source — such files compile to .css instead of publishing
verbatim through the static copy. The extension must be lowercase
.scss, matching what the compiler's glob picks up — other casings
keep publishing verbatim.
The variable a base_url = "${SITE_URL}" still names because it is
unset. base_url stays empty and the build refuses to run without a
--base-url (see require_resolved_base_url!); serve, which always
supplies its own, and the commands that only read config keep working.
The variable a base_url = "${SITE_URL}" still names because it is
unset. base_url stays empty and the build refuses to run without a
--base-url (see require_resolved_base_url!); serve, which always
supplies its own, and the commands that only read config keep working.
Prefix a site-internal root-relative path (e.g. /posts/x/) with
base_path so generated URLs resolve under a subpath deployment.
Absolute http(s):// URLs and paths that are not root-relative are
returned unchanged; a no-op when base_path is "" (domain-root deploy).
Callers that may hold a path without a leading slash (e.g. some
page.url values) should normalize it first — this helper only
prefixes values that already start with "/".