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 ownindex.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.mdisday-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?
- Lists, tags and series: lists of your own, their order, and pages of a list
- Addresses:
permalinkpatterns, old addresses and sending readers on - Templates: which template builds a page, and what it can show
- Dates and languages: how dates look, time zones and translations
Something unclear or wrong? Open an issue on GitHub.