A lightweight Python static site generator for technical blogs.
Apethon keeps the framework separate from your Markdown content. A site repository contains its own content/, static/, and site.yaml; Apethon turns them into plain static HTML.
- clean URLs (
/post/hello) - responsive three-column article layout and dark mode
- Markdown, raw HTML, tables, footnotes, code highlighting, and KaTeX-compatible math
- categories, tags, archive, directory indexes, pagination, search, RSS, and sitemap
- canonical, Open Graph, Twitter Card, and JSON-LD metadata
redirectFromand legacy.htmlredirects- optional build-time Excalidraw-to-SVG export (Node.js 18+ required)
Pinned GitHub release:
uv add "apethon @ git+https://github.com/ApeCodeAI/apethon.git@v0.1.2"Or run it without adding a permanent dependency:
uvx --from "git+https://github.com/ApeCodeAI/apethon.git@v0.1.2" apethon --helpuvx --from "git+https://github.com/ApeCodeAI/apethon.git@v0.1.2" apethon init my-blog
cd my-blog
uvx --from "git+https://github.com/ApeCodeAI/apethon.git@v0.1.2" apethon build -c site.yamlA site has this shape:
my-blog/
├── site.yaml
├── content/
│ └── post/
│ └── hello-world.md
└── static/
Minimal site.yaml:
title: My Technical Notes
brand_name: Ada Lovelace
description: Notes about computing and engineering.
author: Ada Lovelace
author_url: https://example.com/about
hostname: https://example.com
lang: en
content_dir: content
static_dir: static
output_dir: public
posts_per_page: 10
rss_count: 10
sidebar_paths: [/post]Minimal article:
---
title: Hello, Apethon
date: 2026-01-01
permalink: /post/hello-apethon
description: My first article.
category: [Engineering]
tag: [markdown]
---
## Hello
Write Markdown and build the site.apethon build -c site.yaml
apethon serve -c site.yaml -p 8000
apethon init my-blogserve includes drafts by default. Production discovery files (RSS, sitemap, and search) exclude drafts.
Supported fields include title, date, permalink, description, category, tag, redirectFrom, publish, image, article, star, and mathjax.
The first-page browser title defaults to brand_name | title. Set home_title in your site config when you want a fully custom title.
For a repository migration, content_metadata_file may point to a JSON manifest whose entries contain a source-relative path, SHA-256 hash, and preserved date_modified:
content_metadata_file: content-metadata.json{
"files": {
"post/hello.md": {
"sha256": "<sha256-of-the-markdown-file>",
"date_modified": "2026-01-02T13:14:15+08:00"
}
}
}Apethon uses the preserved date only while the file hash still matches; once the article changes, its current Git modification date takes over. A null date preserves the normal publication-date fallback. This avoids rewriting article frontmatter and remains stable in shallow deployment clones.
Place a scene in static/ and reference it from Markdown:
When Node.js is available, Apethon installs its optional exporter dependencies on first use, creates an SVG, rewrites the rendered image reference, and excludes the source scene from public output.
uv sync --group dev
uv run pytest
uv buildApethon 是一个面向技术博客的 Python 静态网站生成器。文章、图片和站点配置保留在独立内容仓库中,框架只负责构建。默认支持代码高亮、数学公式、目录、搜索、RSS、Sitemap、结构化数据和 Excalidraw 转 SVG。
MIT