Start
Starting a site
statac new makes a whole working site from four questions, and later
turns on sharing cards or brings the starter’s files up to date.
Make a site
statac new my-site
A new site in `my-site`.
Enter takes the answer in brackets.
What is the site called?
[My Site] >
What will its address be?
Enter for none yet.
>
What language is it written in?
For more than one, the main one first, as `en, fr`.
[en-GB] >
How should dates look?
1 31 December 2025
2 December 31, 2025
3 2025-12-31
Or type an example of your own.
[1] >
Enter takes the answer in brackets, and --yes takes them all. With no
terminal, as from a script, statac new reads
its answers as lines.
| Given | Statac |
|---|---|
| A folder that isn’t there yet | Makes it, and the site in it. |
| An empty folder | Makes the site in it. |
| No folder | Makes the site in the folder it is run in, which must be empty. |
Where anything stops it part way, such as a full disk, it leaves the folder as it found it.
What does it ask?
| Question | Sets | Enter takes |
|---|---|---|
| What is the site called? | title |
The folder’s name read as words: my-site is My Site. |
| What will its address be? | url, starting https:// or http://, as https://example.org |
Nothing, until you know it. |
| What language is it written in? | language, a code such as en, en-GB or fr. For several, the main one first: en, fr. |
The computer’s own, from LC_ALL, LC_MESSAGES or LANG, or else en. |
| How should dates look? | date_format: the language’s own look, the month first where the site is in English, the year first, or an example of your own. Three shorter dates follow from it. |
1, the main language’s own look. |
Change any answer later in statac.yaml.
With no terminal, statac new reads each line on standard input as the
answer to the next question:
printf 'Site 1\nhttps://example.org\n' | statac new my-site
An empty line takes the answer in brackets, as does each question left when the lines run out: here the language and the dates.
Without an address, feeds, the sitemap and robots.txt wait for one:
no site address.
The date choices are written in the site’s main language, as
31. Dezember 2025 in German. An example of your own is read as
how dates look describes. A
language Statac has no words for is offered the year first alone: see
languages.
What does it write?
statac new --yes my-site
Made a new site in `my-site`: 83 files.
Times are in Europe/London, as this machine is set.
statac.yaml:
title: My Site
language: en-GB
timezone: Europe/London
date_format: 31 December 2025
date_short: 31 Dec 2025
date_day: 31 Dec
date_stamp: 31 Dec 2025, 15:04
feed_key: 27e0d434-c88d-87dd-bd24-4a6ec42e48e6
Next: `cd my-site`, then `statac serve`.
timezone is the computer’s own. feed_key is made fresh for each
site: see entry ids.
The starter lists every file:
| Folder | What’s in it |
|---|---|
my-site/ |
statac.yaml, the site’s settings, and .gitignore, which keeps .statac/ and _site/ out of the site’s history. |
content/ |
Your writing: the home page; posts/, notes/ and photos/, each with its own page and a few samples; the 404 page, the sitemap and robots.txt. |
templates/ |
The templates each kind of page, the feed, the sitemap and robots.txt are built in. |
snippets/ |
Snippets: pieces of HTML you call by name, such as a picture with its caption or a post in a list. |
snippets/markdown/ |
How two pieces of the writing are built: a picture and a callout written in Markdown. |
data/ |
words.yaml: every word the pages show readers, for each language. |
languages/ |
Only for a site in another language: the two lines Statac has in English alone, for you to translate. |
assets/ |
site.css, the one stylesheet, light and dark as the reader’s own setting chooses. |
static/ |
favicon.ico, a sample icon browsers show in the site’s tab: put your own in its place. |
The samples are dated the day you run statac new and the days before
it. One post, “What a post can hold”, shows everything a page’s writing
can hold, each beside how it is written. Every file is yours to change
or remove.
Most files start with a line saying what they build and where these
pages describe it, as a path such as /pictures/.
Everything a reader sees is in the starter’s files, with two exceptions,
and a file of your own takes the place of either:
code.css, the colours for code, and
six pieces of the writing, built as
plain HTML.
The shorter dates
| Line | What it is for | Day first | Month first | Year first |
|---|---|---|---|---|
date_format |
A date written whole: a post’s, a photograph’s | 31 December 2025 |
December 31, 2025 |
2025-12-31 |
date_short |
A date in a list of lines, and beside a related post | 31 Dec 2025 |
Dec 31, 2025 |
2025-12-31 |
date_day |
A post’s day under its year’s heading | 31 Dec |
Dec 31 |
12-31 |
date_stamp |
A note’s date and time, and what a note with no title is called | 31 Dec 2025, 15:04 |
Dec 31, 2025, 15:04 |
2025-12-31 15:04 |
date_format is Statac’s setting. The other three are values of the
site’s own, which a template hands to the
date filter:
{{ post.date | date(site.date_short) }}.
From an example of your own, statac new writes them in the example’s
order, with no weekday and the month’s short word:
Wednesday, 31 December 2025 gives 31 Dec 2025, 31 Dec and
31 Dec 2025, 15:04.
Change any of them in statac.yaml, but keep the lines: the starter’s
templates read all three.
The heading over each year’s posts, and the year at the foot of every
page, come from an example in the template itself, date("2025").
The home page and the lists
The home page opens with its greeting and what content/index.md
says. Under that is a part for each folder that has posts, with a link
to its own page reading “See all”:
| Folder | Its part of the home page | Written by |
|---|---|---|
Any but notes and photos, such as posts |
Its 5 newest posts, each a line: the date, the title, and the post’s summary or else its opening |
{{ line(post) }} |
notes |
Its 2 newest notes, each whole | {{ short(post, nested=true) }} |
photos |
Its 6 newest photographs, in a row | {{ thumb(post) }} |
The parts come in that order. Each heading is the title of the
folder’s own page, such as content/notes/index.md, and so is each link
in the menu.
- A folder you add, such as
content/links/with its ownindex.md, has its link once it holds another page, and its part once that page has a date. Its pages are built as plain pages until itsindex.mdhands them a layout, aspages.layout: post: see hand fields down. - A dated page loose in
content/is in no part of the home page while the site has any folder. - A site with no folders lists every post on the home page, under
“Latest posts”.
content/index.mdsaysposts_per_page: 0, which keeps that list to one page. Take the line out to show ten to a page: see pages of a list.
The menu lists Home, then the site’s folders in the order of their
addresses, with notes and photos last. A folder inside another has a
link too, once it holds a page besides its index.md. To change which
come last, change this line of templates/base.html:
{% set last = ["notes", "photos"] %}
The posts’ own page, and a tag’s or a series’, show more of each post
under a heading for each year: its day, its title, its cover picture
and its opening, by {{ entry(post, pictured=true) }}.
{{ entry(post) }} leaves the picture out.
A post’s opening ends at a <!--more--> line, or else is its first
paragraph: see excerpts.
Which template builds each page
| Folder | Its own page | Each page in it |
|---|---|---|
content/posts/ |
folder.html, naming no layout |
post.html, by pages.layout: post |
content/notes/ |
notes.html, by layout: notes |
note.html, by pages.layout: note |
content/photos/ |
photos.html, by layout: photos |
photo.html, by pages.layout: photo |
The home page is built with home.html, a tag’s or a series’ page with
folder.html, /404.html with 404.html, and any other page with
page.html: which template builds a page has the
rule.
To show a list another way, change the call in its template. line,
entry, short and thumb each write a list item, so each goes inside
<ol> or <ul>.
Notes and photographs
A note is a short page with a date and, most often, no title. Add one as
a file in content/notes/:
---
date: =now
---
A few lines.
content/notes/index.md hands every note
untitled: true. A note with no title
is called by its date and time, as date_stamp writes them, wherever a
title would stand. One snippet does this for every template:
{{ called(post) }}, in snippets/called.html.
A photograph is a folder in content/photos/ holding the picture, and
an index.md naming it as the cover:
---
title: Photo 7
date: =today
cover: photo-7.jpg
---
What the picture shows.
Describe the picture for readers who can’t see it, as pictures says.
- A note’s page shows its title where it has one, its date and
time, its writing, its tags and the notes either side. It shows no
cover,summaryor related posts, whatever its front matter says. - A photograph’s page shows the picture first and wide, then its
title, date and writing. The photographs’ page is a grid of squares,
30 to a page so that each row of three is full:
posts_per_page: 30incontent/photos/index.md. - Webmentions show only on posts. On a note or a photograph,
mentions: trueonly says where other sites send them: see webmentions.
To do without notes or photographs, delete content/notes/ or
content/photos/. Its part of the home page and its link in the menu
go with it.
The templates and snippets that built it stay, and do no harm:
templates/note.html, templates/notes.html and snippets/short.html
for notes, and templates/photo.html, templates/photos.html and
snippets/thumb.html for photographs. Remove them too if you like:
--update then names them as files that aren’t here.
Change what the pages show
The starter’s templates read these fields:
| Field | Where | What it does |
|---|---|---|
summary |
A page’s front matter | A line about the page: under its title (not on a note or a photograph), in the home page’s lines, and in a link preview. |
updated |
A post’s front matter | The day it was last changed, as updated: 2026-10-04, shown beside its date after “Updated”. |
cover |
A post’s or a photograph’s front matter | A picture beside the page, as cover: photo-1.jpg: at the top of a post, and beside its opening in a list that shows pictures. In content/photos/ it is the photograph, and its square in the grid. |
contents |
A post’s front matter | contents: true shows a table of contents above the writing. |
mentions |
A post’s front matter | mentions: true shows the post’s webmentions beneath it. |
greeting |
content/index.md |
The home page’s heading, Hello. on a new site. Without it, the heading is the site’s title. |
tagline |
statac.yaml |
A line about the site: the feed’s <subtitle>. |
author |
statac.yaml |
Who writes the site, in the feed and at the foot of every page, in place of the site’s title. |
date_short, date_day, date_stamp |
statac.yaml |
The shorter dates. The only three that aren’t optional. |
The first post is a folder, to keep its picture beside it. A post with
no picture can be one file, such as content/posts/second-post.md.
Another language, or several
Every word the starter’s pages show readers, such as “Older posts”, is
in data/words.yaml under each language’s code:
the starter’s words says how to
translate them.
Naming several languages, as en, fr, writes language: [en, fr] and a
home page for each language besides the main one, in a folder of its
own: content/fr/index.md. The starter’s base.html links each page to
its translations, with a switch
between them.
Statac has the words for a footnote’s way back to the text, and the
callouts’ names, in English alone, so statac new writes both into
languages/<code>.yaml for you to translate.
A site in several languages covers language folders, lists and addresses.
Turn on sharing cards
statac new --cards
Run it in the site’s folder, or give it the folder. It writes the card’s six files and nothing else. From the next build, once the site has an address, a sharing card is drawn for each page:
| Folder | What’s in it |
|---|---|
templates/ |
og.yaml, the card’s settings: its background, its fonts, and the texts drawn. |
templates/og/ |
The plain background, and two fonts with their licences: Noto Sans, and Noto Emoji, which an emoji in a card’s text is drawn in. |
Given a folder that is empty or isn’t there, as
statac new --cards my-site, it asks the four questions and makes the
site with its card from the start.
It never writes over a file of yours. Turning cards on has the rest.
Bring the starter up to date
statac new --update
Once written, the starter’s files are yours, so a later Statac’s better starter never reaches a site already made. Run this in the site’s folder, or give it the folder, to bring it in.
Updated `templates/base.html`.
`templates/post.html` is yours and wasn't touched. Since the starter file nearest to it, the starter's has changed:
@@ line 12
<h1>{{ headline(page) }}</h1>
-<p>{{ page.date }}</p>
+<p><time datetime="{{ page.date | moment }}">{{ page.date }}</time></p>
{% if page.tags %}
Updated 1 file. 1 of yours has something new, shown above.
Lines starting - left the starter file and lines starting + came.
@@ line 12 is where the change starts in the newest version.
| What it finds | What it does |
|---|---|
| A starter file you never changed | Replaces it with the newest version. |
| A text file you changed | Leaves it, and shows what is new in the starter, for you to copy in what you want. |
| A file you changed that isn’t text, such as the card’s font or background | Leaves it, and names it where the starter’s has changed. |
A word the starter’s templates show that a language’s list in data/words.yaml lacks |
Adds it in English, and names it. |
| A starter file the site doesn’t have | Names it, and writes it only with --missing. Never one in content/posts/, content/notes/ or content/photos/. |
| A starter file that is a link, or is in a folder that is one | Names it and leaves it alone. |
Nothing is kept in the site to tell your files from the starter’s. A file holding exactly what some version of the starter’s did is one you never changed. A file you changed is held to the version nearest it, and what is new is what changed in the starter since.
Where no file has anything new, --update says:
Nothing to update: every starter file here is the newest, or yours with nothing new.
The card’s files are brought up to date like any other, on a site that
has templates/og.yaml. On one without, only --cards writes
them.
Words a newer template shows
Added 2 words to `data/words.yaml` under `en-GB`: `minutes`, `all`.
Updated 1 file.
This is the one time --update writes to a file you may have changed.
It adds each word a newer template shows, in English, at the end of
that language’s list, and changes nothing else in the file. Translate
them as you did the others.
Files that aren’t here
2 starter files aren't here: `snippets/quote.html`, `templates/photos.html`. To write them, run `statac new --update --missing`.
A starter file the site doesn’t have may be one you removed, or one new
in this Statac, so --update names them and writes none. --missing
writes each of them:
statac new --update --missing
Wrote `snippets/quote.html`.
Wrote `templates/photos.html`.
Updated 2 files.
The starter’s files in content/posts/, content/notes/ and
content/photos/ are never named and never written back.
On a site with templates/og.yaml, a card file it lacks is among the
missing, so a site that already has cards can get the emoji font, Noto
Emoji.
Where next?
- Serving a site while you write: the new site in a browser, built again on every save
- Lists, tags and series: a folder’s list, pages of a list, and pages without titles
- Templates: what the starter’s templates can show, and how one sits inside another
- Dates and languages: how dates look, a site in several languages, and the starter’s words
Something unclear or wrong? Open an issue on GitHub.