Update README and AGENTS

This commit is contained in:
2026-04-13 13:11:34 +02:00
parent 19017bf136
commit 316551d263
2 changed files with 114 additions and 5 deletions

View File

@@ -32,9 +32,13 @@ The entire API surface should stay minimal:
| Method | Path | Behaviour |
|--------|------|-----------|
| GET | `/{path}` | If folder: render `index.md` + list contents. If file: serve raw. |
| GET | `/{path}?edit` | Mobile-friendly editor with `index.md` content in a textarea |
| POST | `/{path}` | Write updated `index.md` to disk |
| GET | `/{path}/` | If folder exists: render `index.md` + list contents. If not: show empty create prompt. |
| GET | `/{path}/?edit` | Mobile-friendly editor with `index.md` content in a textarea |
| POST | `/{path}` | Write `index.md` to disk; creates the folder if it does not exist yet |
Non-existent paths without a trailing slash redirect to the slash form (GET only — POSTs
are not redirected because `path.Clean` strips the trailing slash from `PostURL` and the
content would be lost).
Do not add endpoints beyond these without a concrete stated need.
@@ -59,6 +63,78 @@ modifiers for new shortcuts.
`data-key` (the `ALT+SHIFT+KEY` shortcut letter). Adding a `data-key` to a button
automatically registers its shortcut — no extra wiring needed.
## Code Structure
The backend is split across three files:
| File | Responsibility |
|------|----------------|
| `main.go` | Server setup, routing, `serveDir`, `handlePost`, `pageTypeHandler` interface, `readPageSettings` |
| `render.go` | Shared helpers: markdown rendering, heading extraction, file listing, icons, formatting |
| `diary.go` | Diary page type: all types, templates, and render functions |
When adding a new special folder type, create a new `.go` file. Do not add type-specific
logic to `main.go` or `render.go`.
## Special Folder Types (`pageTypeHandler`)
Folders can opt into special rendering by placing a `.page-settings` file in them.
Format: one `key = value` per line; `#` lines are comments.
```
# example
type = diary
```
The server walks up from the requested path looking for a `.page-settings` file. When
found, it determines the depth of the current path relative to that root and dispatches
to the matching `pageTypeHandler`.
**Interface** (defined in `main.go`):
```go
type specialPage struct {
Content template.HTML
SuppressListing bool
}
type pageTypeHandler interface {
handle(root, fsPath, urlPath string) *specialPage
}
```
`handle` returns `nil` when the handler does not apply. `SuppressListing` hides the
default file/folder table (used when the special content replaces it).
**Registering a new type:** implement the interface in a new file and register via
`init()`:
```go
func init() {
pageTypeHandlers = append(pageTypeHandlers, &myHandler{})
}
```
`serveDir` iterates `pageTypeHandlers` and uses the first non-nil result. It has no
knowledge of specific types.
### Diary type (`diary.go`)
Activated by `type = diary` in a `.page-settings` file. Folder structure:
```
Root/ ← .page-settings (type = diary)
YYYY/ ← depth 1 — year view (month sections + photo counts)
YYYY-MM-DD Description.ext ← photos live here, named with date prefix
MM/ ← depth 2 — month view (day sections with content + photos)
DD/ ← depth 3 — day view (index.md content + photo grid)
index.md
```
Photos are associated to days by parsing the `YYYY-MM-DD` prefix from filenames in the
year folder. No thumbnailing is performed — images are served at full resolution with
`loading="lazy"`. The year view shows only photo counts, not grids, for performance.
## Auth
- Basic auth is sufficient — this is a personal tool on a private VPN
- Do not over-engineer access control

View File

@@ -25,6 +25,39 @@ GOOS=linux GOARCH=arm go build -o datascape .
|--------|-----|
| Browse | Navigate folders at `/` |
| Read | Any folder with `index.md` renders it as HTML |
| Edit | Append `?edit` to any folder URL, or click **Edit** |
| Save | POST from the edit form writes `index.md` to disk |
| Edit | Append `?edit` to any folder URL, or click **[EDIT]** (Alt+Shift+E) |
| Save | POST from the edit form writes `index.md` to disk; folder is created if needed |
| New page | Click **[NEW]** (Alt+Shift+N), enter a name — opens the new page in edit mode |
| Files | Drop PDFs, images, etc. next to `index.md` — they appear in the listing |
Navigating to a URL that does not exist shows an empty page with a **[CREATE]** prompt.
## Special Folder Types
A folder can opt into special rendering by adding a `.page-settings` file:
```
type = diary
```
### Diary
Designed for a chronological photo diary. Expected structure:
```
FolderName/
.page-settings ← type = diary
YYYY/
YYYY-MM-DD Desc.jpg ← photos named with date prefix
MM/
DD/
index.md ← diary entry for that day
```
| View | What renders |
|------|-------------|
| Year (`YYYY/`) | Section per month with link and photo count |
| Month (`MM/`) | Section per day with entry content and photo grid |
| Day (`DD/`) | Entry content and photo grid |
Days with photos but no `index.md` still appear in the month view and can be created by clicking their heading link.