ZettelkastenWiki
Created: 03-07-2026 · Last updated: 11-07-2026
Static knowledge-site generator for Zettelkasten-style Markdown wikis:
resolving [[wikilinks]], SEO meta, JSON-LD structured data, reciprocal
hreflang, client-side search, sitemap, a data-driven quiz engine, render
hooks for theming — and a reusable invariant test harness so every
consumer site gets link/SEO/hreflang/<h1> checks for free.
Extracted from the generator behind samskrtam.ru/faq (ORS-FAQ, ~170-test suite). Dependency-free core (Python ≥ 3.10, stdlib only); OG card rendering is an optional extra.
pip install zettelkastenwiki # core
pip install zettelkastenwiki[og] # + Pillow for OpenGraph card PNGs
(PyPI availability verified 03-07-2026: zettelkastenwiki was free — the
fallbacks zettelkasten-wiki and zkwiki were also free and are not used.
First publish gates on the owner's PyPI Trusted-Publisher setup; see
release.yml.)
Quick start
from pathlib import Path
from zettelkastenwiki import GroupSpec, SiteConfig, publish
config = SiteConfig(
base_url="https://example.org/kb",
site_name="My knowledge base",
wiki_root=Path("wiki"),
groups=(
GroupSpec(name="guides", nav_label="Guides", home_style="cards", jsonld_type="article"),
GroupSpec(name="faq", nav_label="FAQ", home_style="accordion", jsonld_type="faq"),
),
)
publish(config, "out/")
Notes are Markdown files with YAML frontmatter in group subdirectories
(wiki/guides/*.md, wiki/faq/*.md). See
example/ for a
complete site the CI builds and smokes: three home styles, a per-group
language with a reciprocal hreflang pair, a themed string table and a quiz
attached through a hook.
What the core gives you
| Concern | Mechanism |
|---|---|
| URLs | folder URLs per note (/group/slug/), slug overrides, transliteration table |
| Wikilinks | [[note]], [[note|label]], [[../group/note]] — every link resolves or points home |
| SEO | canonical, meta description, OG/Twitter cards, seo_title/seo_description frontmatter |
| Structured data | per-group JSON-LD (article / faq / course / webpage), breadcrumbs, WebSite+SearchAction |
| i18n | zero hardcoded UI literals — a Strings table + pluggable date formatter; per-group lang |
| hreflang | reciprocal pairs from alt_<lang> frontmatter, x-default on the primary language |
| Search | lazy-loaded client-side index (search.json) over titles/aliases/terms |
| Quizzes | one data-driven engine (QuizSpec: router or scored mode) instead of copy-pasted script blocks |
| Theming | Hooks: head extras, body top/bottom, per-note extras, home body, card visuals, shortcuts, mobile CTA, nav, extra CSS |
| Testing | zettelkastenwiki.testing.run_all(out, config) — links resolve, unique descriptions ≤160, single <h1>, self-canonical, reciprocal hreflang, JSON-LD parses, sitemap coverage, search index |
| OG cards | optional [og] extra — branded 1200×630 PNGs with a content-addressed render cache |
Design decisions (owner rulings D1–D7, 03-07-2026)
| # | Decision | Ruling |
|---|---|---|
| D1 | Packaging | Standalone package repo; ORS-FAQ = consumer #1 (no template copies) |
| D2 | Scope | Core + plugin hooks; quizzes-content/CTA/ladder/trust-bar stay consumer plugins; core is language-neutral |
| D3 | Positioning | Knowledge-site lane; csl-guides stays Docusaurus for structured docs |
| D4 | Pilots | kosha, SanskritLexicography article site, SamudraManthanam, MWS |
| D5 | Repo home & name | gasyoun/ZettelkastenWiki |
| D6 | Sequencing | Extraction ran as the top agent track, parallel to other work |
| D7 | Distribution | PyPI from day one (Trusted Publishing, no token secrets) |
Full roadmap: ROADMAP_ZETTELKASTENWIKI_2026.md.
Consumers
| Site | Angle | Status |
|---|---|---|
| ORS-FAQ → samskrtam.ru/faq | source of the extraction | ✅ live — migrated behind a golden-diff byte-parity gate (publish.py 3,074→1,812 lines); 168-test suite green |
| kosha → gasyoun.github.io/kosha/docs-site | greenfield | ✅ live — 5 notes + ~50-line config on the existing legacy Pages |
| SamudraManthanam → samskrtam.ru/corpus-faq | same hosting | ✅ live — 6 RU notes; second FTP site on the shared deploy path |
| SanskritLexicography research site | consolidation | ✅ merged (PR #107) — 10 scattered convention docs → one site, zero per-file edits (v0.2.0 defaults layer) |
| MWS | docs-per-repo probe | ✅ probed → drove the v0.2.0 defaults layer; no upstream PR (org batched-PR cadence) |
| Uprava (private) | AI-memory site | ✅ v0.3.0 pilot, extended Wave-6 (04-07-2026) — 124-note searchable memory (root docs + handoffs + archive) from the live repo via multi-root ingest, full-text body search, git recency, backlinks (107 pages), H### auto-linking (262 prose links) & a status-index home (Hub/In-work/Queued/Done/Archived); Wave-6 added a repos group: one consolidated note per recently-active (7-day) sibling repo, staged from that repo's recovered .ai_state.md history + commit log + org-memory mentions (61 repos as of 04-07-2026, via tools/build_repo_memory_notes.py); built locally, never published |
Use cases
-
Product FAQ / support site — the origin case (ORS-FAQ): notes with CTAs, quizzes, testimonials, SEO/JSON-LD, hreflang for a lead-gen funnel. Live at samskrtam.ru/faq.
-
Project docs / knowledge base — a repo's own explainer site from a
wiki/of Markdown (kosha, SamudraManthanam): nav + search + sitemap + JSON-LD for free from ~50 lines ofSiteConfig. -
Docs-per-repo consolidation — publish frontmatter-less Markdown already sitting in a repo (
docs/,research/, conventions) with zero editing via the defaults layer (title_from_h1,source_filter,<h1>injection, v0.2.0) — proven on SanskritLexicography's scattered convention docs. -
AI / agent memory browser — turn a commit-heavy repo's accumulated Markdown memory (handoffs,
.ai_state.md,FINDINGS.md,ROADMAP*.md, decision logs) into a searchable, cross-linked, status-ranked site a fresh agent session navigates instead of grepping. Built out in v0.3.0–v0.6.0:- multi-root in-place ingest — one site from several repo dirs, no copying;
- full-text body search — match content, not just titles (hyphen-safe);
- git recency — last-commit date badge + newest-first ordering;
- backlinks — per-note "Referenced by" from wikilinks, Markdown/URL
.mdlinks, and auto-linked tokens; H###auto-linking — bare handoff/issue tokens in prose become links;- status-index home — a GTD-style bucketed landing (in-work / done / archived) with counts.
Proven on a private Uprava memory site (built locally, never published) — ~126 notes as of 04-07-2026, and growing with the repo: full-text search over every body, 107 pages of backlinks, 262 auto-linked
H###references.
Roadmap
Waves 1–3 (extract → migrate ORS-FAQ → pilot four consumers) are done; the
defaults layer (v0.2.0) proved arbitrary docs-per-repo publishing with zero
edits. Wave 5 shipped (v0.3.0): multi-root in-place ingest, full-text body
search, single-<h1> enforcement, git recency, backlinks, H###
auto-linking and a status-grouped index home — all proven on a private
Uprava memory site (~126 notes as of 04-07-2026, and growing).
AI-memory building blocks (v0.3.0–v0.6.0):
- ✅ Multi-root ingest (v0.3.0) — one site from several source dirs
(
handoffs/,docs/, root*.md) with no copying, viaGroupSpec.source_dir/recursive/pattern/exclude. - ✅ Recency & provenance (v0.4.0) —
git_recencyfills each note's last-commit date/author;GroupSpec.sort="recency"orders newest-first and the date becomes the page badge. - ✅ Auto-linking (v0.5.0) —
autolink_patternsturns bare tokens likeH103in prose into links to the note they name (tag-aware, feeds the backlink graph); resolves relative/URL.mdlinks too. - ✅ Backlinks (v0.4.0) —
backlinksrenders a per-note "Referenced by" from the reverse link graph (wikilinks + Markdown/URL.mdlinks). - ✅ Status-grouped memory index home (v0.6.0) —
status_home+status_of+status_bucketsrender the home as a GTD-style bucketed index (counts summary + per-status sections, newest-first). - ✅ Full-text body search (v0.3.0) —
full_text_searchindexes cleaned bodies (hyphen/slash-preserving) so "have we hit this before?" matches content. - CI freshness gate — a reusable action that rebuilds the memory site on every push so it never drifts from the repo (the staleness-guard pattern the pilots already use, packaged).
Open questions steering this are in the roadmap doc: ROADMAP_ZETTELKASTENWIKI_2026.md.
Development
pip install -e .[dev]
python -m pytest tests -q
python example/build.py /tmp/example-site
MIT. Provenance: extracted 03-07-2026 by Fable 5 (claude-fable-5) per
H077.
Dr. Mārcis Gasūns
Release files for zettelkastenwiki 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zettelkastenwiki-0.6.1.tar.gz | 51.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zettelkastenwiki-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 92.8 kB
Release files / zettelkastenwiki-0.6.1.tar.gz
| Download URL | zettelkastenwiki-0.6.1.tar.gz |
|---|---|
| Size | 51.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c239b7cea1a4c3e8ca2d11442315fd9194c25ec3af0500fc832894dc8a4a8ad
|
|
BLAKE2b-256 checksum How to use checksums |
107552912d62f292d6abe7e68472f87199cafff35161efae5552f15409049808
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Release files / zettelkastenwiki-0.6.1-py3-none-any.whl
| Download URL | zettelkastenwiki-0.6.1-py3-none-any.whl |
|---|---|
| Size | 41.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4d20494aee4c219889b7a9370a0fba1f4c1f6e73050f84d79d639ec6542ae073
|
|
BLAKE2b-256 checksum How to use checksums |
2a95679e9507940ce33d9207c2ed3d089cb0dd4a7a849079e1e193a1281faf55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|