Layouts
Document chrome, layout selection and the render order.
A layout is a module in app/layouts that exports layout. It receives the rendered page as slot.
module RootLayout {
use Cataract;
proc layout(ctx: Context, slot: string, ref meta: PageMeta): string {
var h = new MarkupBuilder();
h.open("header");
h.el("a", "Home", "href", "/");
h.close();
h.open("main");
h.raw(slot);
h.close();
return h.done();
}
}Selection
A layout is named by its file: app/layouts/root.chpl is root. A page selects one with a module-level param:
param layout = "docs";Pages default to root, and a project with pages must have a root layout — the scanner reports its absence as a build error rather than letting chpl fail on a missing symbol.
Render order
page -> layout -> document shellLayouts run after the page and before the shell, which means a layout can still set fields on meta: a canonical URL derived from ctx.path(), a title suffix, a body class derived from the section being viewed. This wiki does all three in one layout.
meta.title = SiteMeta.pageTitle(meta.title);
if meta.canonical.isEmpty() then meta.canonical = SiteMeta.canonical(ctx.path());
meta.bodyClass = sectionClass(ctx.path());Two layouts, one shell
Multiple layouts are ordinary: a documentation layout with a sidebar, a marketing layout without one. Both end at the same document shell, so <head>, lang, stylesheet links and the client runtime tag stay in one place.
A layout may itself declare an island, in which case every page using that layout ships the client runtime — which is how a search box lands on every page of a site without each page opting in.