1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Build and run
go build ./cmd/iblog
./iblog serve [--port 8080] [--root .]
# Hot reload during development (uses air)
air # serves on :8081 per .air.toml
# Run all tests
go test ./...
# Run a single test
go test ./internal/db/... -run TestPostSearch
# User management
./iblog user add <name>
./iblog user list
./iblog user passwd <name>
./iblog user delete <name>
# Build frontend JS (from assets/lib/ or assets/admin/lib/)
cd assets/lib && bun run build
cd assets/admin/lib && bun run build
```
## Architecture
iblog is a Go blog engine with an admin UI. It uses a hybrid model: posts are authored via a browser-based editor, stored in SQLite, and then rendered to static HTML files in `public/` for serving.
**Data flow:** Admin UI (EditorJS) → SQLite (`data/iblog.db`) → static HTML (`public/`) → served to readers
**Key packages:**
- `cmd/iblog/` — CLI entry point with `serve` and `user` subcommands
- `internal/` (package `auth`) — htpasswd-compatible bcrypt password file; nginx can use the same file via `auth_basic_user_file`
- `internal/db/` — SQLite wrapper; schema includes `posts`, `pages`, `redirects`, `settings`, and an FTS5 virtual table (`pages_fts`) for full-text search
- `internal/server/` — Gin HTTP handlers: `adminserver.go` (admin CRUD, auth middleware, setup flow), `frontpage.go`, `posthandler.go`, `fileserver.go`
- `internal/builder/` — Converts EditorJS block JSON to HTML (`editorjs.go`)
- `internal/media/` — Image upload, processing (govips/libvips), and serving
**Frontend assets** are embedded into the binary via `embed.go`:
- `assets/lib/` — Shared site JS (thumbhash, built with bun → `dist/`)
- `assets/admin/lib/` — Admin editor JS (EditorJS + plugins, built with bun → `dist/`)
- `assets/components/` — Custom web components served to the public site
- `assets/styles/` — CSS
- `templates/` — Go `html/template` files; `templates/admin/` for admin UI
**Directory layout at runtime** (controlled by `--root`):
```
data/iblog.db SQLite database
data/.passwords htpasswd file (bcrypt, 0600)
data/media/ uploaded media originals + processed images
public/ generated static HTML output
components/ optional user-supplied web components
styles/ optional user-supplied CSS overrides
```
**Setup flow:** On first run (no password file), all requests redirect to `/setup` where the first admin user is created. After that, `/admin/` routes require HTTP Basic Auth.
**Static generation:** Saving a post in the admin UI writes HTML to `public/<slug>/index.html` and updates the FTS5 index. The `public/` directory is served as a fallback for any route not matched by dynamic handlers.
## Notes
- `govips` wraps libvips; libvips must be installed on the host (`brew install vips` on macOS).
- The JS bundles in `assets/*/lib/dist/` are committed — rebuild them with bun when changing JS dependencies.
- Posts store content as raw EditorJS JSON (`blocks` column) and render to HTML on publish, not on read.
|