Expand description
Content staging — residual upstream-gap workarounds for the
staticdatagen → staticweaver → metadata-gen pipeline.
§v0.0.46 residual scope
Most of v0.0.45’s shim layer was retired in v0.0.46 by upstream fixes:
staticdatagen 0.0.10(closes upstream#67,#68,#69,#70,#71) handles missinglayout:keys, absentmain.js/sw.js, absent tags-page templates, nested-locale walk (_posts/<lang>/), and success-log ordering natively.staticweaver 0.0.3(closes upstream#28) added theEngine::with_lax_undefined(true)opt-in.staticweaver 0.0.3also madeescape_html_intoidempotent (closes ssg #589).rss-gen 0.0.6(closes upstream#34) prefixed validation errors withchannel./item.context and accepts relative URLs at item level.metadata-gen 0.0.5(closes upstream#20) collapses multi-line double-quoted YAML scalars internally.
What remains here are two narrow gaps the upstreams haven’t closed yet:
-
Template-default injection.
staticdatagen 0.0.10doesn’t yet opt the staticweaver Engine intolax_undefined(tracked at staticdatagen #99), so unresolved{{ var }}tags still abort the build.collect_template_vars+stage_content_with_template_defaultspre-fill an emptyvar: ""for every key the templates reference but the content omits. -
Multi-line quoted-scalar collapse.
staticdatagen 0.0.10pinsmetadata-gen = "0.0.4"(the pre-#20 release; tracked at staticdatagen #100).copy_tree(the per-file staging helper) applies the same collapse pass that’s now upstream inmetadata-gen 0.0.5, so the user’s content sees consistent behaviour regardless of whichmetadata-genis transitively resolved.
Both shims auto-retire when the corresponding staticdatagen follow-up releases — the residual module shrinks to nothing.
§Permalink derivation (spec A2/B1, plan §2 item 1.2, issue #586)
staticdatagen’s RSS generator hard-fails the whole build when a
post lacks permalink: front matter (rss-gen: “channel.link is
missing”). Because every page passes through this stager before
staticdatagen::compile, the stager can make that failure
unreachable: when a staged .md file’s frontmatter carries
neither permalink nor url, stage_content_with_site_defaults
injects permalink: "{base_url}/{relative_output_path}" derived
via crate::urls::derive_permalink. Author-specified permalinks
always win — files that already declare permalink or url pass
through verbatim. Only YAML --- fenced frontmatter flows through
this stager (the template-default shim shares the same
constraint); files without a frontmatter block are left untouched.
§Why staging instead of editing in-place?
The user’s checkout is sacred:
- the build runs from a CI checkout the user expects to be read-only;
- reruns of the build would re-inject defaults, doubling lines.
Instead we operate on a fresh directory under
std::env::temp_dir() (FNV-1a-keyed by build_dir + pid) that’s
recreated on every build.
Functions§
- collect_
template_ vars - Walks
template_dirrecursively and returns the sorted, deduped set of every{{ <var> }}reference found in the template files. - inject_
missing_ keys - Injects empty
key: ""entries into the frontmatter block for anykeynot already present. No-op for files without a frontmatter block. - inject_
missing_ keys_ with_ values - As
inject_missing_keys, butderivedsupplies real values for the keys it names instead of the empty-string placeholder. - inject_
permalink_ if_ missing - Injects
permalink: "<permalink>"as the first key of the YAML frontmatter block when the block exists and declares neitherpermalinknorurl(spec A2/B1, plan §2 item 1.2, issue #586). - stage_
content_ with_ site_ defaults - Like
stage_content_with_template_defaultsbut also derives apermalink:for staged.mdfiles that don’t declare one. - stage_
content_ with_ template_ defaults - Stages a copy of
content_dirand injects empty defaults for every{{ var }}reference the templates make.