Opinionated static site generator.
Find a file
2025-07-05 16:01:15 -04:00
src/zona added show_title frontmatter option 2025-07-05 16:01:15 -04:00
tests added packaged template resources 2025-06-27 21:51:30 -04:00
.gitignore init python project 2025-06-15 19:10:48 -04:00
.python-version init python project 2025-06-15 19:10:48 -04:00
justfile update deps, add util config 2025-06-15 21:52:26 -04:00
LICENSE added license 2025-06-15 19:27:20 -04:00
pyproject.toml removed marko dependency 2025-07-05 02:34:33 -04:00
README.md update readme 2025-07-05 02:48:10 -04:00
uv.lock removed marko dependency 2025-07-05 02:34:33 -04:00

Zona

Zona is an opinionated static site generator written in Python. From a structured directory of Markdown content, Zona builds a simple static website. It's designed to get out of your way and let you focus on writing.

Note: This project is in early development, and there are no versioned releases yet. For an example of a website built with Zona, please see ficd.ca

Features

  • Live preview server with automatic rebuilding.
  • jinja2 template support with sensible defaults included.
    • Basic page, blog post, post list.
  • Glob ignore.
  • YAML frontmatter.
  • Easily configurable sitemap header.
  • Site footer written in Markdown.
  • Smart site layout discovery.
    • Blog posts automatically discovered and rendered accordingly (can be overridden in frontmatter).
  • Extended Markdown renderer:
    • Smart internal link resolution.
    • Syntax highlighting.
    • Image labels.

When Zona encounters links in Markdown documents, it attempts to resolve them as internal links. Links beginning with / are resolved relative to the content root; otherwise, they are resolved relative to the Markdown file. If the link resolves to an existing file that is part of the website, it's replaced with an appropriate web-server-friendly link. Otherwise, the link isn't changed.

For example, suppose the file blog/post1.md has a link ./post2.md. The HTML output will contain the link /blog/post2 (which corresponds to /blog/post2/index.html). Link resolution is applied to all internal links, including those pointing to static resources like images.

Syntax Highlighting

Zona uses [Pygments] to provide syntax highlighting for fenced code blocks. The following Pygments plugins are included:

  • pygments-kakoune
    • A lexer providing for highlighting Kakoune code. Available under the kak and kakrc aliases.
  • pygments-ashen
    • An implementation of the Ashen theme for Pygments.

If you want to use any external Pygments styles or lexers, they must be available in Zona's Python environment. For example, you can give Zona access to Catppucin:

# config.yml
markdown:
  syntax_highlighting:
    theme: catppucin-mocha

Then, run Zona with the following uv command:

uvx --with catppucin zona build

Image Labels

A feature unique to Zona is image labels. They make it easy to annotate images in your Markdown documents. The alt text Markdown element is rendered as the label — with support for inline Markdown. Consider this example:

![This **image** has _markup_.](static/markdown.png)

The above results in the following HTML:

<div class="image-container"><img src="static/markdown.png" title=
""> <small>This <strong>image</strong> has
<em>markup</em>.</small></div>

The image-container class is provided as a convenience for styling. The default stylesheet centers the label under the image.

Installation

Zona is not yet packaged on PyPI. You may use uv to install it from this repository:

uv tool install 'git+https://git.sr.ht/~ficd/zona'

Usage

_Note: you may provide the --help option to any subcommand to see the available options and arguments.

To set up a new website, create a new directory and run zona init inside of it. This creates the required directory structure and writes the default configuration file. The default templates and default stylesheet are also written.

To build the website, run zona build. The project root is discovered according to the location of config.yml. By default, the output directory is called public, and saved inside the root directory.

To start a live preview session, execute zona serve. The server will run until it's killed by the user, and the website is rebuilt if any source files are modified.

Site Layout

The root of the Zona project must contain the configuration file, config.yml, and a directory called content. A directory called templates is optional, and prioritized if it exists. public is the built site output — it's recommended to add this path to your .gitignore.

The content directory is the root of the website. For example, suppose your website is hosted at example.com. content/blog/index.md corresponds to example.com/blog, content/blog/my-post.md becomes example.com/blog/my-post, etc. Internal links are resolved relative to the content directory.

Markdown files inside a certain directory (content/blog by default) are automatically treated as blog posts. This means they are rendered with the page.html template, and included in the post_list, which can be included in your site using the post_list.html template.

Frontmatter

WIP

Configuration

WIP