Content and front matter

spork-site 0.1.1

Discover CommonMark documents with persistent metadata, structural content, and canonical routes.

Markdown documents use optional YAML front matter:

---
title: First Post
date: 2026-08-30T12:00:00Z
summary: A post built with Spork.
tags: [spork, release]
---
## Hello

```python
print("Spork")
```

Discovering a content directory returns an eager persistent vector of document maps:

(ns example.content
  (:require [spork-site.content :as content]))

(def documents (content.load-documents "content"))

Each document contains front-matter fields at the top level plus canonical fields:

{:source-path   #p"content/blog/first.md"
 :relative-path "blog/first.md"
 :id            "blog/first"
 :slug          "first"
 :route         "/blog/first/"
 :metadata      {:title "First Post" :tags ["spork" "release"]}
 :body          "## Hello\n..."
 :content       (Fragment [...])
 :title         "First Post"
 :date          #inst"2026-08-30T12:00:00Z"}

YAML mappings and sequences become persistent maps and vectors. YAML dates remain Python date/datetime values. Front-matter sets are rejected because they are unordered.

Routes are derived from relative paths:

SourceRouteOutput
index.md/index.html
docs/index.md/docs/docs/index.html
blog/hello.md/blog/hello/blog/hello/index.html

Use slug, route, permalink, or url front matter to override the derived route. Explicit routes are validated and canonicalized.

Pass :patterns to select several deterministic globs, or disable highlighting when loading:

(ns example.options
  (:require [spork-site.content :as content]))

(content.load-documents
  "content"
  * :patterns ["docs/**/*.md" "blog/**/*.md"]
    :highlight? false)