Repository navigation
Releases
Folia 0.2.0
The second pre-1.0 release of Folia, the Rust static-site generator behind
ggirelli.info. It adds a local preview server, preview builds of drafts
and scheduled posts, reproducible builds as of a moment, and the first release binary.
Read this first. Like 0.1.0, this is a release of the software. It does not mean the
Jekyll site has been replaced, or is ready to be: Folia's output equals Jekyll's for most of the
reference site and differs, on purpose or known, for the rest
(known limitations). Folia is
fully vibe coded: tested, not
audited, and provided without warranty. It is built for one website and is not a general-purpose
static-site generator.
What is new
-
folia servebuilds the site, serves it on a local address and builds it again when a file
changes, reloading the open pages. Each rebuild is stamped with the local time of day
([14:03:22] Changed: …). See
Previewing while you write and its
limitations.A rebuild writes only the files whose bytes changed, and removes those the build no longer
makes, instead of replacing the whole destination. On a slow disk this is the difference
between minutes and seconds: the reference site rebuilt in about 90 s into a USB drive, and
now in about 2 s. Each file is still replaced whole, never served half-written. -
Preview builds:
folia buildandfolia servetake--future(documents dated after the
build) and--unpublished(documents whose front matter sayspublished: false). A preview
build is not for publishing, andfolia buildrefuses to replace a normal build with one, or
the reverse. See
Previewing drafts and scheduled posts. -
folia build --at <TIME>builds as of an RFC 3339 timestamp instead of now, so the same
sources give the same site on any day. See
Building as of a moment. -
Redirect stubs in the site's colours: a
[redirects]table withbackgroundand
color-schemepaints the stubs Folia writes forredirect_fromfrom their first frame, so an
old URL no longer flashes a white page on a dark site. Without it, a stub is as before. See
[redirects]. -
page.lang: the front matterlangof a post, garden note, micro entry or page reaches
templates as written ([italian]oritalian), and is absent without one. -
noindex: a page's front matter may saynoindex: true, which its template sees as
page.noindex(falseby default), so a site can keep one page, such as its 404, out of
search results by writing a robots tag. Before, the key was refused and the page skipped. -
A release binary: a release workflow builds
foliafor Linux x86_64 from the tag, with a
SHA-256 checksum and a build-provenance attestation. See
Install and Releasing. -
Documentation: a user guide (getting started, content, templates,
building and deploying, feeds, sitemap and search), a
guide to migrating from Jekyll, and the parity tools reduced to a
reference for that exercise. The design plans were removed from the docs; they remain in the git
history. -
Checks: the Jekyll parity checks moved out of
just checkintojust check-parity, so the
default check needs no Ruby.
Upgrading from 0.1.0
Nothing in a 0.1.0 site's sources or configuration needs to change. A dark site may add
[redirects] to colour its redirect stubs. If your feeds name Folia's version as their
generator, update it to 0.2.0. A destination written by a preview build (--future or
--unpublished) is refused by a normal folia build, and the reverse: build previews into a
directory of their own.
Install
Download folia-v0.2.0-x86_64-unknown-linux-gnu.tar.gz and its .sha256 file from this release,
or build from source (cargo build --release -p folia). See
Getting started.
Known limitations
Unchanged from 0.1.0, plus those of folia serve: every change rebuilds the whole site, a git
commit alone triggers nothing, and the served site's URLs are local. See
Known limitations.
Folia 0.1.0
The first pre-1.0 release of Folia, the Rust static-site generator behind
ggirelli.info.
Read this first. 0.1.0 is a release of the software: it builds the reference site, its checks
pass, and it refuses to destroy what it did not write. It does not mean the Jekyll site has
been replaced, or is ready to be. Folia's output equals Jekyll's for most of the reference site
and differs, on purpose or known, for the rest; the site's owner decides whether that is enough
for publishing it. Folia is also fully vibe coded:
tested, not audited, and provided without warranty. It is built for one website and is not a
general-purpose static-site generator.
What it is
folia build reads a site (a git repository of Markdown and HTML sources, templates and a
configuration) and writes the static site to a directory.
Content it builds
| Kind | What |
|---|---|
| Pages | Markdown and HTML pages with explicit permalinks, redirects (redirect_from, as stubs and redirects.json), tables of contents, covers, an error page |
| Blog | posts dated by file name, categories, tags, previous and next, the paginated index with featured posts, one archive per category, the categories and tags pages |
| Microblog | notes, likes, bookmarks and RSVPs, each with its own template, and listings that claim a page and list entries |
| Digital garden | notes with wiki-links, backlinks and the note graph (notes_graph.json) |
| Assets | static files copied as they are; Sass stylesheets compiled with Dart Sass, with source maps |
Documents without a title are titled as Jekyll titles them. Front matter Folia does not know is
refused rather than ignored.
Generated outputs
- Feeds: Atom feeds for the blog, each tag, micro entries (and each kind), the garden, and a
combined feed, written asjekyll-feed0.17 wrote them. - Sitemap:
sitemap.xml, asjekyll-sitemap1.4 wrote it (the URL set is the same; the
order and static files'lastmoddiffer, see below). - Search: the search script's
documentsarray, followed by the site's own code.
Using it
folia build --site path/to/site --dest path/to/out # --config defaults to <site>/_folia/folia.toml
folia --version- Configuration:
_folia/folia.tomlin the site (time-zone,exclude,[site],[roots],
[authors.*],[micro],[garden],[blog],[feeds],[search],[sass]); the public
example site shows each
table, and Development describes them. A key Folia does not know is an error. - Prerequisites: to build Folia, a stable Rust toolchain (edition 2024) and git; to build a
site with Sass stylesheets, Dart Sass exactly 1.100.0 (sassonPATHorFOLIA_SASS);
to run the checks,just, uv, Node.js, Ruby with Bundler, Python 3 andcargo-deny. The
manual testing guide lists the commands that installed all
of it on a fresh Ubuntu 24.04. There is no prebuilt binary and no crates.io release: build from
source (cargo build --release -p folia). - Templates are MiniJinja and strict: a template that reads a value a page does not have is an
error, not an empty string.
Safety guarantees
These are tested with unit tests and with the real binary (crates/folia/tests/cli_safety.rs).
--destis written only if it is absent, empty, or a directory a previous Folia build wrote
(a record beside it names it and lists what it held). Anything else (your files, a moved copy,
a directory with something added) is refused and nothing in it is touched. Folia never deletes
what it did not write, and refuses leftover temporary directories rather than removing them.- The output is built beside the destination and swapped in last, so a failed build leaves the
previous output exactly as it was. - A missing or failing template, a render error or an unknown author fails the build with every
problem listed, naming the template and the pages. Nothing is skipped silently: only documents
Folia does not support yet are skipped, and each is named. - Exit status:
0built,1the build failed (nothing written),2usage or configuration
error.
Known limitations and intentional differences from Jekyll
Documented in full in Known limitations. In short:
- Exact parity with Jekyll is not reached, and is not claimed. The parity tooling separates a
clean build (every output accounted for) from exact parity (every output identical), and a
documented difference is not identical output. On the reference site, most outputs are
identical or differ only as the owner approved; some differ on purpose or are known. - On purpose: feed
<updated>is the newest item's date, not the build time; the sitemap
lists pages by URL and dates static files by their last commit; the search index includes micro
entries and joins no words across line breaks (an improvement on Jekyll's); category and tag
pages do not link feeds that never existed; a tag with a space gets a feed. - Not built yet: page types other than Markdown and HTML, Liquid in HTML pages,
last_modified_aton pages; syntax highlighting uses syntect, not Rouge (the token classes
differ in a few percent of blocks). - Source defects it reproduces, such as links written without a scheme, are recorded by the
site's owner, not guessed at.
Verification at release
Unit and integration tests, just check (formatting, clippy pedantic, tests, docs, cargo deny,
linters, negative checks of the parity scripts, the docs build) and CI on Ubuntu; the example
site builds and serves from a clean Ubuntu 24.04; the reference site builds deterministically
(two builds are byte-identical) and its Markdown parity holds for every document.
Documentation
Home, Development, Manual testing
(install, build, serve, troubleshooting), Known limitations,
Parity baselines, How it is made and the
plans.