Papyrus.py is a lightweight, extensible Python static site generator that builds a complete website from Markdown content, Jinja templates, and static assets. Papyrus is adapted from the Cacty.py SSG developed by Claudio Santini. Papyrus expands on Cacty.py by introducing categories and making it easier to add template converters via classes.
Papyrus runs in your command line and builds your site from templates you define:
python3 papyrus.pyPapyrus is designed for simple publishing workflows:
- Create templates and pages in
templates/ - Write posts in
posts/*.md - Build HTML into
build/ - And optionally, run watch mode with a local preview server
- Markdown-to-HTML post generation
- Post metadata support (title, author, date, category, draft)
- Category taxonomy page generation
- Template-driven pages via Jinja (
templates/*.html,templates/*.xml) - Static asset copying (
static/->build/static/) - Site variable management via
config.toml - Local development mode with file watching and auto-rebuilds
- Built-in HTTP preview server (
http://localhost:8246)
Papyrus manages the whole build process. Upon running python papyrus.py, the script:
- Loads
config.tomland updatesbuild_date - Builds post pages from Markdown (
posts/) usingtemplates/post.html - Groups posts by category and builds category pages using
templates/category.html(if present) - Builds top-level pages from
templates/(excluding partials and collection templates) - Copies
static/files intobuild/static/
In watch mode (-w), it monitors project files and rebuilds when changes are detected, then serves the generated site.
Download and copy the git repo to your project folder, or in the project folder, run in your Terminal:
git clone https://github.com/cealigbe/papyrus.gitto clone the repository.
This is the minimum viable file structure for Papyrus to generate your website.
.
├── papyrus.py
├── config.toml
├── posts/
│ └── *.md
├── templates/
│ ├── _base.html
│ ├── post.html
│ ├── category.html
│ └── *.html / *.xml
├── static/
└── build/ # generated output
These are the Python dependencies needed to run Papyrus
- Jinja2
- Markdown
- toml
- watchdog
- jinja-markdown
- pymdown-extensions
- PyYAML
Prior to running Papyrus, install the requirements by running the following:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtpython papyrus.py [options]Papyrus currently has one argument -w which builds once, then:
- watch files for changes
- auto-rebuild on changes
- start local server on
http://localhost:8246
# Build once
python papyrus.py
# Build + watch + serve
python papyrus.py -wPosts in posts/*.md should use metadata headers.
Example:
---
title: My Post
description: Short summary of the post
author: Jane Doe
category: engineering
date: 2026-04-05
draft: false
---
Post body in Markdown.dateis required and must be inYYYY-MM-DDformat.draft: trueexcludes a post from output.categorydefaults touncategorizedif omitted.
Papyrus renders templates from templates/:
post.html— individual post page templatecategory.html— category listing template (optional)- Other top-level
.html/.xmlfiles — rendered as site pages - Files beginning with an underscore (
_) are treated as partials and skipped as standalone pages
Templates receive site/page data and collections:
site(fromconfig.toml)pagemetadata (id, type, build date)postslist (for pages listing posts)categorieslist (for pages listing categorized posts)
Generated files are written to:
build/posts/*.htmlbuild/categories/*.htmlbuild/*.htmlandbuild/*.xmlbuild/static/**
- Update
config.toml - Create/edit posts in
posts/ - Create/update templates in
templates/ - Run
python papyrus.py -w - Open
http://localhost:8246
Papyrus.py is extensible for your specific web development needs. You can use papyrus_filters.py to add functions to Papyrus, as well as additional page generation classes. An example Folio class and build function are provided for building portfolio collection pages.
There are also additional scripts:
papyrus_post.py: creates a starter markdown post file with metadata inposts/for quick bloggingpapyrus_setup.py: generates a minimum viable file structure for running Papyrus, complete with templates, CSS, and Javascript files to speed up your web developmentsitemappr.py: a simple script that generates a sitemap from the files output inbuild/. Run after your latest Papyrus site build
- My website, chuck.aligbe.com
- And hopefully yours; feel free to submit it here
config.tomlis rewritten during builds to persist updatedbuild_date. Make sure to stop the testing server before updated the config file.- Unknown CLI flags are ignored; only
-wis currently recognized. Other CLI flags coming soon.
Papyrus is adapted from the Cacty.py SSG developed by Claudio Santini. Papyrus is also inspired by other SSGs which help generate clean and semantic static websites.
This project is distributed under the MIT License, see LICENSE for more info.
Found a bug or have a suggestion? Feel free to open an issue or submit a pull request!
