Custom projections (schema extension modules)
Model domain data — a language's builtins, a CLI surface — as typed blocks in a schema module, then project them into generated reference pages.
When a topic has recurring domain data the four unit kinds don't capture — the builtin functions of a language, the subcommand tree of a CLI, a keybinding table — model it as its OWN schema and project it, instead of flattening it into prose facts. The pattern is a *schema extension module*: a .wcl file declaring typed @blocks plus a merging @document that gathers them.
// schema/keybindings.wcl — a topic-specific extension module
namespace wcl.wskill
@block("keybinding")
type Keybinding {
@inline(0) id: identifier
keys: utf8
action: utf8
context: utf8?
}
// Merges with the base @document — `keybindings` gathers only where imported.
@document
type KeybindingDoc {
@children("keybinding") keybindings: list<Keybinding>
}
Import the module from wskill.wcl, author instances in data/, then add a render to each projection template — typically a wdoc_repeater generating one page (or one table row) per instance. Because imported @document schemas MERGE with the base, the extension composes cleanly with everything else.
The wcl wskill is the worked example at scale: its schema/builtins.wcl and schema/cli.wcl modules capture 80+ builtin functions and the whole wcl subcommand tree as data, projected into generated per-function and per-command reference pages. Two standard modules ship with every wskill — the presentation and training views use exactly this mechanism.
§ 1Examples
§ 1.1A typed custom block
Declare an @block plus a @document that gathers it; imported documents merge with the base. Then add a render to both template sets.
@block("keybinding")
type Keybinding {
@inline(0) id: identifier
keys: utf8
action: utf8
context: utf8?
}
@document
type Extensions {
@children("keybinding") keybindings: list<Keybinding>
}