Statac

Write

Front matter

Front matter is the lines at the top of a page that Statac and your templates read. In content/post-1.md:

---
title: Post 1
date: 2026-10-04
tags: [Rust, Go]
layout: post
---
The writing starts here.

It is YAML, between two --- lines. Each line is a field, a name and a value, which a template shows as page. and the name: {{ page.title }}.

Fields Statac reads

Statac reads the fields in these tables. Any other name is a field of your own.

About the page

Field What it does Example
title The page’s title. Without it, the page’s opening # heading is its title. title: Post 1
untitled true where the page is meant to have no title, as a short note is: Statac calls it by its date. A folder usually hands it down: see pages without titles. untitled: true
summary A line about the page. summary: The first post.
date The page’s date: see write a date. date: 2026-10-04
updated When the page last changed, written as a date is. updated: 2026-10-06
draft true leaves the page out of the build: see drafts. draft: true
layout The template the page is built with. On a page with each:, the template of the pages it makes. layout: post
type What kind of page this is, in a word of your own. Where templates/ has a template of that name and the page names no layout, the page is built with it. type: book

Where it is published

Field What it does Example
permalink Where the page is published, or a pattern such as /{year}/{slug}/: see choosing an address. permalink: /about/
redirect_from Old addresses of the page, each sending readers on to it. redirect_from: [/old/post-1/]
redirect_to Where readers arriving at the page’s address are sent instead. The page publishes nothing else. redirect_to: /posts/post-1/
needs needs: url leaves the page out until the site has a url, as a sitemap needs: see sitemaps. needs: url
translation_key Links the page to its translations where their names differ: the pages with the same key. translation_key: about

Tags, series and neighbours

Field What it does Example
tags The page’s tags, as a list in brackets. tags: [Rust, Go]
series The one series the page is part of. series: Series 1
neighbours Which list page.previous and page.next walk: site, folder, series, or false for none. See previous and next. neighbours: series

On a page that speaks for a list

A folder’s index.md speaks for the folder’s list, and any page can choose a list of its own: a page that speaks for a list.

Field What it does Example
posts A list of the page’s own, chosen from every post. posts: site.posts
each Makes a page for each item of a table in data/, or with each: site.posts, for each post. See pages made from data and a page for each post. each: data.people
order Which way the list runs, newest first or oldest first, or the names of its pages in the order you want. order: oldest first
numbered In a folder’s index.md, false where the numbers opening its pages’ names are part of the names. numbered: false
posts_per_page How many posts each page of the list shows, 0 for all of them on one. posts_per_page: 20
index_page false publishes nothing at the list’s address, and no later pages. The list still works in templates. index_page: false
feed Where the list’s feed goes, as a name or an address; true for one on a list that has none unless asked; false for none. See which lists have a feed. feed: atom.xml

A posts: line, or each: site.posts, keeps some posts with the filters tagged, in and where:

posts: site.posts | in("blog") | tagged("Rust")

Feeds, sharing and webmentions

Field What it does Example
id What a post is known by in a feed, wherever it moves. See when a post moves. id: fc370633-88f0-8092-9f96-7749dbfff0eb
card Which of the site’s sharing cards the page is drawn, once cards are turned on. card: wide
og_image A picture the page is shared with in place of a card. og_image: cover.jpg
og_title What the page is called on a card and in a link preview. og_title: A shorter title
mentions true where the page shows its webmentions, for a layout to read as page.mentions. mentions: true

Write a date

Written What it is
2026-10-04 A day.
2026-10-04 09:30 A day and a time. A T can stand for the space: 2026-10-04T09:30.
2026-10-04 09:30:15 The same, with seconds.
2026-10-04 09:30 +01:00 A moment, with its offset from UTC: Z, +01:00, +0100 or +01, after a space or not.

A date is written year first, and one with no offset is read on the site’s timezone. A file named 2026-10-04-post-1.md takes its date from its name. Dates and languages has how dates look on the page.

Let Statac write the date

In content/post-1.md:

---
title: Post 1
date: =today
---

A stamp stands for a date until Statac writes the date over it. statac serve does so as it starts and each time you save, and statac stamp does every stamp in the site at once.

Stamp What it writes Written on Tuesday 6 October 2026 at 14:07
=today Today, on the clock of the site’s timezone. 2026-10-06
=tomorrow, =yesterday The day after today, and the day before. 2026-10-07, 2026-10-05
=monday to =sunday The next such day after today. On a Monday, =monday is a week away. =friday writes 2026-10-09
=now The date and time, to the minute. 2026-10-06 14:07
Any stamp but =now, then a time That day, at that time. =monday 09:00 writes 2026-10-12 09:00

A post stamped with a day to come waits for it.

  • A stamp is the whole of a value, in any field of front matter: one of Statac’s, one of yours, one nested beneath another, or an item of a list.
  • Anywhere else it is text: in the writing, in statac.yaml, in a data file or in a template. So is a value that only begins with =, such as =IF(A1).

Stamp before a build

statac build and statac check never write a date, and stop at a stamp. Before them, run:

statac stamp
Stamped `content/post-1.md`: `date` is `2026-10-06`.

It writes the date over every stamp in the site and says each one. Besides the feed ids a site with write_feed_ids: true asks for, it changes nothing else in a file.

Name the site’s folder after the command, or with --site=<folder>, as for statac build. --today=<date> gives the day to count from, and =now is then that day’s midnight.

Hand fields down to many pages

A line starting pages. hands a field down to many pages at once. In statac.yaml, it reaches every page:

pages.layout: post

In a folder’s index.md, it reaches every page inside that folder and the folders within it:

---
title: Posts
pages.layout: post
pages.summary: One of the posts.
---

A page’s own line comes first, then the nearest folder’s, and so on out to statac.yaml. A folder’s index.md is handed the lines of the folders above it, never its own. From statac.yaml, a line also reaches the home page and the pages Statac makes for tags and series.

Field handed down What it acts on
Your own fields, and the rest of Statac’s, such as layout, tags or card The pages it reaches.
order, feed, index_page Each page it reaches that speaks for a list, such as a sub-folder’s index.md. From a folder, never the folder’s own list. An order of names counts only on a list’s own page.
neighbours Each page it reaches that doesn’t speak for a list.
title, date, id, needs, redirect_from, redirect_to, translation_key, posts, each, numbered, posts_per_page Nothing: each page has its own.

Write each line flat, as pages.layout: post, and in statac.yaml where it is for every page. A page with each: hands its pages. lines to the pages it makes.

Add fields of your own

In content/post-1.md:

---
title: Post 1
book:
  author: Author 1
  isbn: 0-000-00000-0
---

A template shows the author as {{ page.book.author }}. A field can hold text, a number, a list, or fields nested beneath it, as book: does. Nest a field the same way on every page.

Some names are Statac’s on every page, such as slug, url, content, source and language: written on a page, the line is set aside.

Declare your fields

In statac.yaml:

fields.isbn: text
fields.rating: number
fields.read: when

Statac then checks the field on every page that writes it.

Kind What a page writes Example
text Text. isbn: 0-000-00000-0
number A number. rating: 4
true/false true or false. signed: true
list A list. formats: [print, audio]
url An address. link: https://example.org/
date A date, written as date is. published: 2026-10-04
when A date, a year and month, or a year. read: 2026-10
one of and the values allowed, as one of book, film One of those values. format: book

required before the kind says every page must have the field. For the pages of one type only, write the declaration under types.:

types.book.isbn: required text

A field nested beneath another is declared by its whole name, on one line, with a dot between each part:

fields.book.author: text
fields.book.published: date
types.review.book.rating: required number

A field that names a record or a page

fields.author: one of data.people
fields.review_of: one of folder.books
Declared Its names A page writes
one of data.people The items of data/people.yaml, by the names they are written under. author: person-1
one of folder.books The pages content/books/ lists, by the names in their addresses. review_of: book-1

A template is handed the name as written.

  • A table is named as each: names it.
  • A folder inside another is named by its path, folder.books/shelf-1. Its names are the pages in it and in the folders inside it, but no folder’s own index.md.
  • A page’s name is the one in its address, whatever its permalink:, without the date it opens with or its number in a numbered folder: 03-day-one.md is day-one.
  • Drafts and posts waiting for their day are names too. On a site in several languages, a page at that path in any language is a name.

Dates in your fields

A template shows a date or when field as the site writes its dates, and can ask one for its parts:

Kind Parts
date year, month and day, and weekday, the day’s name in the page’s language.
when year, always. month where one was written, and day where the whole date was.

Each part but weekday is a number. Guard a part a field may not have: {% if page.read.month is defined %}.

Sorted, when fields go in the order of the calendar, among themselves and among whole dates: 2025, 2025-10, 2025-10-04, 2026.

When does a value need quotes?

Written YAML reads it as Write instead
version: 3.10 The number 3.1. version: "3.10"
version: 1e3 The number 1000. version: "1e3"
version: 0x10 The number 16. version: "0x10"
colour: #F2E9D3 A comment, which leaves the line with no value. colour: "#F2E9D3"

Statac takes a bare value as typed where YAML’s reading keeps every character, so title: 1984 is the text 1984.

A field of yours that isn’t declared as text is read as YAML reads it, so version: 3.10 there is the number 3.1. Quotes make a value text.

A text in quotes that runs onto more lines needs each later line indented at least two spaces deeper than the line it opens on.

Where next?

Something unclear or wrong? Open an issue on GitHub.