mirror of
https://github.com/kbenestad/mdcms.git
synced 2026-06-18 07:24:31 +00:00
Merge pull request #3 from kbenestad/claude/add-claude-documentation-upu1E
Add CLAUDE.md with codebase documentation for AI assistants
This commit is contained in:
commit
994af5bec7
1 changed files with 127 additions and 0 deletions
127
CLAUDE.md
Normal file
127
CLAUDE.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## What this project is
|
||||
|
||||
MD-CMS is a markdown-based static site system with two distinct parts:
|
||||
|
||||
1. **`mdcms.py`** — a zero-dependency Python 3 CLI tool (standard library only). It scans content, generates `nav.yml` and `search.json`, validates config, and packages a zip for deployment.
|
||||
2. **`website/index.html`** — a single-file browser renderer that reads markdown, config, and nav at runtime entirely client-side. There is no build pipeline, no compilation, no server.
|
||||
|
||||
The `website/` folder is the deployable artifact. `mdcms.py` lives outside it.
|
||||
|
||||
## Running the CLI
|
||||
|
||||
```bash
|
||||
python3 mdcms.py
|
||||
```
|
||||
|
||||
This opens an interactive menu. Key options:
|
||||
|
||||
| Option | Action |
|
||||
|--------|--------|
|
||||
| 1 | Validate config + nav, rebuild search.json, export `website.zip` |
|
||||
| 2 | Interactive wizard to create `config.yml` and folder structure from scratch |
|
||||
| 3 | Scan `pages/` and `posts/`, write `nav.yml` and `search.json` |
|
||||
| 4 | Rebuild `search.json` only (faster, for content-only updates) |
|
||||
| 5 | Check and interactively fix `config.yml` issues |
|
||||
| 6 | Check and interactively fix `nav.yml` issues |
|
||||
| 7 | Register/switch website paths (stored in `~/.mdcms/paths.json`) |
|
||||
| 8 | Start `python3 -m http.server 8800` and open browser |
|
||||
|
||||
**Local preview:** Always use option 8 (or run `python3 -m http.server 8800` in `website/`) rather than opening `index.html` directly — browsers block local file access due to CORS.
|
||||
|
||||
## Architecture of `mdcms.py`
|
||||
|
||||
The file is a single-module Python script with these logical layers, in order:
|
||||
|
||||
1. **Path registry** — `~/.mdcms/paths.json` stores named project paths. `active_path()` returns the currently selected project.
|
||||
2. **Frontmatter parser** (`parse_frontmatter`) — reads `---` YAML blocks with a hand-rolled parser (no PyYAML). Returns a flat `{key: value}` dict with type coercion (bool, int, quoted strings).
|
||||
3. **Category system** — category codes are parsed from `config.yml` by `parse_config_categories()`. Variant files use `basename.<code>.md` naming (e.g. `about.nb.md`). `identify_variant()` only recognises a suffix as a category code if it appears in the declared code list.
|
||||
4. **Scanner** (`scan_and_categorize`) — walks `pages/` or `posts/`, skips drafts (`draft: true` in frontmatter), returns records including first 5000 chars of body for search indexing.
|
||||
5. **Nav/search generators** — `generate_nav_yml()` and `generate_search_json()` produce the output files. `parse_nav_yml()` is a hand-rolled parser for reading back nav.yml (not a general YAML parser — only handles the exact format it emits).
|
||||
6. **Validators** (`validate_config`, `validate_nav`) — return lists of `{field, issue, current}` dicts for display; used in options 1, 5, and 6.
|
||||
7. **Menu actions** (`do_*` functions) — one per menu option, called by `main_menu()`.
|
||||
|
||||
## Content structure inside `website/`
|
||||
|
||||
```
|
||||
website/
|
||||
index.html ← renderer (edit to change site behaviour)
|
||||
config.yml ← required: sitename, navigation; rest optional
|
||||
nav.yml ← generated; manual edits to section metadata are preserved on rebuild
|
||||
search.json ← generated
|
||||
pages/
|
||||
home.md ← default landing page
|
||||
about.md ← default variant
|
||||
about.nb.md ← Norwegian variant (category suffix = nb)
|
||||
posts/
|
||||
2025-01-01-my-first-post.md
|
||||
assets/
|
||||
fonts/
|
||||
images/
|
||||
```
|
||||
|
||||
## Page frontmatter fields
|
||||
|
||||
All optional except `title`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: Page Title
|
||||
sort: 100 # controls nav ordering (lower = higher)
|
||||
section-id: blog # assigns page to a nav section
|
||||
draft: true # exclude from nav and search
|
||||
author: Name
|
||||
date: 2025-01-01
|
||||
datetime: 2025-01-01 13:00 # use this for posts (not `date` alone — see known limitations)
|
||||
modified: 2025-01-15 09:00
|
||||
keywords: foo, bar
|
||||
description: Short description for search
|
||||
language: en
|
||||
---
|
||||
```
|
||||
|
||||
## nav.yml structure
|
||||
|
||||
Sections and pages are separate lists. `mdcms.py` preserves manual edits to section fields (`defaultname`, `sort`, `parent`, `parent-sort`, `pagesvisibility`, `categorynames`) on each rebuild. New sections are auto-created from `section-id` values found in frontmatter.
|
||||
|
||||
`pagesvisibility` can be `visible`, `hidden`, or `draft` (draft excludes pages from `search.json`).
|
||||
|
||||
For nested navigation, set `parent: <parent-section-code>` and `parent-sort` on a section.
|
||||
|
||||
## Category system
|
||||
|
||||
- `categories-use: yes` in `config.yml` enables categories
|
||||
- `default-category.code` is required when categories are enabled
|
||||
- Variant files: `<base>.<code>.md` — the suffix is only treated as a category if the code is declared in config
|
||||
- `categories-sectionnames: per-category` requires each section in `nav.yml` to have a `categorynames` block with an entry per category code
|
||||
- RTL is set per category via `direction: rtl`
|
||||
|
||||
## Dynamic post tags (mdcms code blocks)
|
||||
|
||||
Embed post lists in pages using fenced blocks:
|
||||
|
||||
````markdown
|
||||
```mdcms
|
||||
posts-datetime-reversechronological
|
||||
limit: 10
|
||||
paginate: yes
|
||||
```
|
||||
````
|
||||
|
||||
Reliable tags (others are known-broken): `posts-datetime-chronological-byyearmonth`, `posts-datetime-reversechronological`. Use `datetime` frontmatter (format: `YYYY-MM-DD HH:MM`) for posts — `date` alone does not work reliably.
|
||||
|
||||
## Known limitations
|
||||
|
||||
- `mdcms.py` always expects the deployable site in a `website/` subdirectory of the registered project path.
|
||||
- Most `posts-*` tag variants are broken. Only `posts-datetime-chronological-byyearmonth` and `posts-datetime-reversechronological` reliably work.
|
||||
- Section headings in the nav are non-clickable (sections-sitemap is not yet implemented).
|
||||
|
||||
## Key implementation details
|
||||
|
||||
- `parse_nav_yml()` and `parse_config_categories()` are **not** general YAML parsers — they only handle the exact indentation/format that `mdcms.py` itself produces. Do not assume they handle arbitrary YAML.
|
||||
- Category code validation uses `CATEGORY_CODE_RE = re.compile(r"^[a-zA-Z0-9\-]+$")` — codes must match this.
|
||||
- The `samplesite/` directory is a reference implementation with multi-language categories (English, Norwegian, Arabic including RTL). It is not deployed; it exists for reference and testing.
|
||||
- `website/` in the repo root is a minimal starter template (single page, no categories).
|
||||
Loading…
Reference in a new issue