How to choose what gets published, where it goes, and how links and images are handled. Every front matter key is in the front matter reference.
Publishing a note
A note is published only if its front matter has a gramr block with publish:
---
gramr:
publish: public # or unlisted
site: blog # or several: [blog, docs]
section: articles/rust # optional
title: Understanding lifetimes
date: 2026-10-30
---
- Without front matter, without
gramr, or withoutpublish, the note is ignored. - A forgotten flag means a missing page, never a leaked note.
- The rest of the front matter (
title,date,taxonomies,extra…) is passed to Zola untouched.
Notes can live anywhere in the source folder: their place on the site comes from the front matter, not from the folder they are in. Hidden folders (.obsidian, .git, .trash…) are never scanned. To scan only part of the folder, see source.include.
Sections
A section is a folder of the site that groups pages, usually with its own listing page. Sections are created in the site repository, not in your notes:
content/
├── _index.md
├── articles/
│ ├── _index.md # listing template, sorting, pagination
│ └── rust/
│ └── _index.md
└── notes/
└── _index.md
A note goes to gramr.section, or to the site's default_section. gramr refuses to publish into a section that does not exist: Zola would render the page but list it nowhere.
Page URL
The page is written to content/<section>/<slug>.md. The slug is the note's slug, else its title slugified, else its file name slugified:
| Note | Page |
|---|---|
Lifetimes.md, title: Understanding lifetimes | understanding-lifetimes.md |
Lifetimes.md, no title | lifetimes.md |
slug: lifetimes-explained | lifetimes-explained.md |
Set slug to keep a URL stable when you rename a note or change its title.
Links between notes
Write links as usual: gramr rewrites them so that Zola resolves them (@/section/page.md).
| In the note | On the site |
|---|---|
[[Note]], [[Note|text]], [[Folder/Note]] | link to the page of Note |
[[Note#Heading]], [[#Heading]] | link to the heading |
[text](Other%20note.md), [text](<Other note.md>), [text][ref] | link to the page |
![[Note]] (embedded note) | link to the page: the content is not inlined |
[[Note#^block]] | link to the page, with a warning: block references have no equivalent |
https://…, mailto:…, /about/, #anchor, @/… | untouched |
How a link is found:
- Wikilinks work like Obsidian: by file name, case-insensitive, anywhere in the source folder. With a
/, by path. - Markdown links are resolved from the note's folder, then from the source folder. A missing target that is not a
.mdfile (../tags/rust/) is left as is: it may be a page of the site. - A name matching several files is an error. Use a path:
[[Folder/Index]].
Links to private notes are removed. A link is replaced by its text when its target does not exist, is not published on this site, or is unlisted while the linking page is public. gramr publish <site> --dry-run lists each one with its reason.
Headings are slugified like Zola's default (slugify.anchors = "on"): [[Note#Elision rules]] links to #elision-rules.
Images and attachments
| In the note | On the site |
|---|---|
![[image.png]],  | image |
![[image.png|300]], ![[image.png|300x200]] | image with width (and height) |
![[image.png|A caption]] | image with A caption as alt text |
![[file.pdf]], [[file.pdf]] | link to the file |
- Only the files referenced by published notes are copied, to
static/assets/<hash>-<name>.<ext>. The hash avoids collisions and hides how your folder is organised. - Images are linked from the site root (
/assets/…): a site served from a sub-path (https://example.com/blog) is not supported yet.
Comments
Obsidian comments (%% … %%) and HTML comments (<!-- … -->) are removed, so they never appear in the page source. An unclosed comment removes the rest of the note, with a warning.
Code is never transformed: links and comments inside inline code or code blocks are left as is.