f7d84b4f0f
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
130 lines
3.3 KiB
Markdown
130 lines
3.3 KiB
Markdown
# SCHEMA — tech blog source files
|
|
|
|
Source-file contract for the tech blog pipeline. Files in `mikkeli/tech-blogs` must follow this contract to be picked up by the auto-publisher.
|
|
|
|
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body is plain markdown, rendered to MediaWiki wikitext by Pandoc.
|
|
|
|
## File layout
|
|
|
|
```markdown
|
|
---
|
|
title: Building a Raspberry Pi Kubernetes cluster
|
|
date: 2026-06-10
|
|
tags:
|
|
- Raspberry Pi
|
|
- Kubernetes
|
|
- homelab
|
|
wiki:
|
|
publish: true
|
|
---
|
|
|
|
# Building a Raspberry Pi Kubernetes cluster
|
|
|
|
... body markdown ...
|
|
```
|
|
|
|
## Fields
|
|
|
|
### Required
|
|
|
|
#### `title` (string)
|
|
|
|
The MediaWiki page name. MediaWiki capitalises the first letter; lowercase input is fine. No prefix is applied — the title is used as-is.
|
|
|
|
#### `wiki.publish` (boolean)
|
|
|
|
Publishing gate. `true` means the pipeline writes this file to the wiki. `false` (or absent) means the file is ignored. `wiki` must be a YAML mapping:
|
|
|
|
```yaml
|
|
# correct
|
|
wiki:
|
|
publish: true
|
|
```
|
|
|
|
### Optional
|
|
|
|
#### `date` (ISO 8601 date)
|
|
|
|
Publication date in `YYYY-MM-DD` format. Drives `[[Category:Blog:<year>]]` injection. If omitted, no year category is added.
|
|
|
|
#### `tags` (list of strings)
|
|
|
|
Topic tags. Each entry becomes `[[Category:<tag>]]` at the bottom of the rendered page. Tags are used as-is — no `Blog:` prefix is added.
|
|
|
|
```yaml
|
|
tags:
|
|
- Raspberry Pi
|
|
- Kubernetes
|
|
- homelab
|
|
```
|
|
|
|
## Body
|
|
|
|
Plain markdown. The body is passed through Pandoc as-is — the first-line `# Heading` is not stripped, so you can use h1 elements freely.
|
|
|
|
## Renderer behaviour
|
|
|
|
For each `.md` with `wiki.publish: true`:
|
|
|
|
1. Parse and validate frontmatter.
|
|
2. Pipe the body through `pandoc -f markdown -t mediawiki`.
|
|
4. Prepend the auto-generated banner: `{{Auto-generated|source=<source URL>|commit=<sha>}}`.
|
|
5. Append category tags: `[[Category:Tech blog]]`; `[[Category:Blog:<year>]]` if `date` is set; `[[Category:<tag>]]` for each tag.
|
|
6. Read the current wiki page content; if identical, skip the write (idempotency).
|
|
7. If the page exists without `{{Auto-generated`, skip with a warning (manual page protection).
|
|
8. Otherwise, write with an edit summary referencing the source commit.
|
|
|
|
## Implemented scope
|
|
|
|
- Frontmatter parsing and validation
|
|
- Pandoc-based markdown → wikitext rendering (h1 elements preserved)
|
|
- Banner template injection
|
|
- `Category:Tech blog` on every published page
|
|
- `Category:Blog:<year>` from `date` field
|
|
- `Category:<tag>` per entry in `tags`
|
|
- Idempotent writes
|
|
- Manual-page protection
|
|
- Files without `wiki.publish: true` silently skipped
|
|
|
|
## Not in scope (intentional)
|
|
|
|
- Namespace prefix — posts live at bare titles
|
|
- Series grouping — use tags for now
|
|
|
|
## Examples
|
|
|
|
### A published post
|
|
|
|
```yaml
|
|
---
|
|
title: Running act_runner in Docker on a Raspberry Pi
|
|
date: 2026-06-01
|
|
tags:
|
|
- Raspberry Pi
|
|
- Gitea
|
|
- CI/CD
|
|
wiki:
|
|
publish: true
|
|
---
|
|
```
|
|
|
|
Categories: `Tech blog`, `Blog:2026`, `Raspberry Pi`, `Gitea`, `CI/CD`.
|
|
|
|
### A draft
|
|
|
|
```yaml
|
|
---
|
|
title: Notes on aarch64 cross-compilation
|
|
wiki:
|
|
publish: false
|
|
---
|
|
```
|
|
|
|
## Validation errors the renderer must produce
|
|
|
|
- Missing or empty `title` on a file with `wiki.publish: true`
|
|
- `wiki.publish` present but not a boolean
|
|
- `date` (if present) does not parse as `YYYY-MM-DD`
|
|
- `tags` (if present) is not a list
|
|
- Two publishable files declare the same `title`
|