The content pipeline

Walk the tree once at start-up, then never touch the disk again.

Updated 2 min read

ContentStore is a module whose top-level const declarations do the work. Chapel initialises a module before anything that uses it, so by the time main binds a socket, every document is parsed, rendered, sanitised and indexed.

private const activeEnvironment: string = detectEnvironment();
private const resolvedRoot: string = resolveRoot();
private const store: list(Document) = loadAll();
private const pathIndex: map(string, int) = buildIndex();
private const docOrder: list(int) = sortedDocs();

Each declaration runs in order, and each is const — so the entire registry is immutable for the lifetime of the process and readable from every connection task without a lock.

The document record

record Document {
  var urlPath: string = "";
  var slug: string = "";
  var title: string = "";
  var description: string = "";
  var section: string = "";
  var order: int = 100000;
  var published: string = "";
  var draft: bool = false;
  var isIndex: bool = false;
  var depth: int = 1;
  var words: int = 0;
  var readingMinutes: int = 1;
  var html: string = "";
  var plain: string = "";
  var plainFold: string = "";
  var titleFold: string = "";
  var descriptionFold: string = "";
  var excerpt: string = "";
  var headings: list(Heading);
}

Three of those fields exist purely so that a request does no work: html is already sanitised, plain is already stripped of markup, and the *Fold fields are already lowercased so that a case-insensitive search is a byte comparison rather than an allocation.

Paths come from the tree

FileURL
content/docs/introduction.md/docs/introduction
content/docs/routing/index.md/docs/routing
content/docs/routing/dynamic-segments.md/docs/routing/dynamic-segments
content/docs/wiki/sanitisation.md/docs/wiki/sanitisation

Every segment is slugified on the way in, and a slug that fails validation is skipped rather than registered. Since a request is resolved by looking its path up in pathIndex, a traversal attempt cannot reach the filesystem: there is no filesystem call left in the request path to reach.

Drafts

if parsed.meta.draft && isProduction() then return;

The environment is read from CATARACT_ENV, or from the --siteEnvironment config const, and defaults to production. A forgotten variable therefore hides drafts rather than publishing them.

Ordering

Documentation sorts by the frontmatter order, then by title, so a section controls its own reading order from its files. The sort runs once, at start-up, and produces a list of indices — a request iterates integers, not records.