Script loading
Registry contract, shape guards, and build details of the plugin loop
Code-level notes for _partials/scripts/plugins.html, the loop
behind params.docsy.plugins. For the architecture and ordering decisions, see
the design notes.
Registry contract
params.docsy.plugins is a list of plugin entries:
params:
docsy:
plugins:
- name: NAME # resolves assets/js/plugins/NAME.js
enable: true # optional; false skips the entry
defer: true # optional; adds `defer` to the script tag
pageGate: FLAG # optional; a .Page.Store flag name
options: {} # optional; reaches the module as @params
- NAME # bare-name shorthand for { name: NAME }
- Names are coerced to strings (
printf "%v"): YAML auto-types entries likename: 2048, and the loop must resolve the same asset path either way. - Registry order is emission order.
- With
pageGateset, the plugin is emitted only on pages carrying the named.Page.Storeflag.
Shape guards
The registry read must not break sites that already carry a params.docsy
value:
- A scalar
params.docsyis left untouched (the read is gated onreflect.IsMap) and the loop emits nothing. - A non-list
params.docsy.plugins, falsy scalars included, warns (docsy-plugins-config) and is ignored. - An entry with no usable name warns (
docsy-plugin-unnamed) and is skipped. - An enabled registration with no asset at
assets/js/plugins/NAME.jswarns (docsy-plugin-missing), regardless ofpageGate, so a typo can’t hide behind a gate.
Warnings are issued with warnidf, so each is suppressible through Hugo’s
ignoreLogs.
Build and emission
- The script asset resolves through the union file system: theme, project, or module-mounted, with a same-named project file shadowing the theme’s.
- Each plugin builds individually with
js.Build; the entry’soptionstravel as buildparams, so the module reads them withimport * as params from '@params'. Production builds addminify. - Fingerprinting runs in every environment, not just production: distinct builds of one source (per-language sites, duplicate registrations with different options) must publish distinct paths, or the last write wins site-wide.
- The script tag carries SRI attributes (
integrity,crossorigin), anddeferwhen the entry sets it.
Companions
Optional companions resolve by naming convention and emit before the script tag (why):
_partials/scripts/plugins/NAME.html: a partial for vendored libraries, component markup, and config-provider patterns; invoked with(dict "Page" PAGE "Plugin" ENTRY).assets/scss/plugins/NAME.scss: a stylesheet compiled through the SCSS pipeline, minified in production, fingerprinted, and emitted with SRI.