feat(manage): add /manage pages to edit caption and date
/manage lists every photo; /manage/edit/{slug} rewrites the photo's
.toml sidecar, which triggers a rebuild. The pages sit behind the same
htpasswd as /upload and are not linked from the public site.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -19,9 +19,18 @@ The binary does three things at once:
|
||||
- Serves a multipart upload API at `POST /upload`
|
||||
- In dev mode (`--serve`), also serves `public/` as static files
|
||||
|
||||
Routes: `GET /upload` (HTML upload form), `POST /upload` (multipart), `GET /health`.
|
||||
Routes: `GET /upload` (HTML upload form), `POST /upload` (multipart), `GET /manage` (list of photos), `GET`/`POST /manage/edit/{slug}` (edit caption and date), `GET /health`.
|
||||
|
||||
In production nginx sits in front: serves `public/` directly, proxies `/upload` to localhost, htpasswd on the upload endpoint. Note `/health` is **not** proxied — nginx only forwards `location /upload`, so anything outside the box can only reach `/upload`.
|
||||
In production nginx sits in front: serves `public/` directly, proxies `/upload` and `/manage` to localhost, htpasswd on both. Note `/health` is **not** proxied — nginx only forwards `location /upload` and `location /manage`, so anything outside the box can only reach those two.
|
||||
|
||||
### Managing photos
|
||||
|
||||
`manage.go` holds the `/manage` handlers, kept apart from the upload code in `server.go`. The pages are rendered on request from the sidecars (not generated into `public/`), and nothing on the public site links to them. Constraints worth knowing before touching it:
|
||||
|
||||
- An edit only rewrites the `.toml` sidecar. Any key other than `caption` and `date` in a hand-written sidecar is dropped, same as on upload.
|
||||
- Slugs from the URL are matched against the photos actually in `content/`, never joined into a path.
|
||||
- `sameOrigin` compares the `Origin` header against `-base-url`, because behind nginx the `Host` header is the upstream address. A wrong `-base-url` therefore breaks saving in browsers that send no `Sec-Fetch-Site`.
|
||||
- Changing a date moves the photo to another day page, but the old `public/day/<date>/` is not removed — the generator never prunes `public/`.
|
||||
|
||||
## Stack
|
||||
|
||||
@@ -143,12 +152,15 @@ nix build # succeeds
|
||||
| `main.go` | Flags, wires generator + watcher + server |
|
||||
| `generator.go` | Scans content dir, renders HTML + Atom feed, generates thumbs/mediums |
|
||||
| `server.go` | Upload API + optional static file serving |
|
||||
| `manage.go` | `/manage` list and edit handlers |
|
||||
| `watcher.go` | fsnotify watcher with 500ms debounce |
|
||||
| `assets.go` | `//go:embed` for templates and static |
|
||||
| `templates/timeline.html` | Site root: photos grouped by day, paginated |
|
||||
| `templates/grid.html` | Flat square grid at `/grid/`, paginated |
|
||||
| `templates/day.html` | Single-day page at `/day/<date>/` |
|
||||
| `templates/photo.html` | Single photo page, neighbour links and prefetch |
|
||||
| `templates/manage.html` | `/manage`: list of photos with edit links |
|
||||
| `templates/edit.html` | `/manage/edit/{slug}`: caption and date form |
|
||||
| `static/photo-nav.js` | Arrow-key and swipe navigation |
|
||||
| `module.nix` | NixOS module (systemd service, tmpfiles, nginx vhost) |
|
||||
| `flake.nix` | `buildGoModule` package + devShell + nixosModules |
|
||||
@@ -162,7 +174,8 @@ nix build # succeeds
|
||||
|
||||
- ActivityPub federation (planned later — start with RSS/Atom)
|
||||
- Multi-image upload
|
||||
- Delete/edit via UI
|
||||
- Delete via UI (edit is done, see Managing photos)
|
||||
- Pruning `public/` when a photo is deleted or its date changes
|
||||
- Any auth beyond nginx htpasswd
|
||||
- The Android app has never been run on real hardware
|
||||
- Photo-page swipe has never been tested on a real touchscreen; the iOS Safari edge-gesture interaction is the untested part
|
||||
|
||||
Reference in New Issue
Block a user