The site now reads all its content from PocketBase over HTTP, one read per
request. The old file-based content layer (Markdown + YAML in Content/) is
gone. Closes#8.
Main changes
Pages, posts, events and FAQs come from PocketBase. A typed PocketBaseClient (registered with AddHttpClient) reads each collection per
request. No content is cached at startup and no FileSystemWatcher is needed —
an editorial change is live right away.
Generic page rendering. One ContentPage (@page "/{Slug}") renders any pages record, so a new page is just a new record — no .razor change. Literal
routes (/posts, /events, /faqs, /) still win over the catch-all.
Navigation is generated from the pages records (header/footer, ordered),
not hard-coded. Pages can also opt into embedded lists (posts/events/faqs) via
an embed field.
English routes:/beitraege → /posts, /termine → /events, /termine.ics → /events.ics.
Removed the dead file content layer (Content/, the reader, and the YamlDotNet dependency).
Docs aligned with the PocketBase reality (architektur.md AE-2/AE-3, CLAUDE.md, redaktion.md, entwicklung.md, recht.md). Legal-text slugs are
now English (imprint, privacy).
Developer experience
A fresh dev volume comes up populated. A dev-only PocketBase migration
creates the collections and inserts example content on the first docker compose up. It is idempotent, mounted only by compose.dev.yaml, and
never runs against production or the tests.
The collection schema has one source. The dev seed and the test fixture
both read the same pb/pb_migrations/collections_schema.json, so the schema
can't drift between them. The test records stay fixed in the fixture on
purpose (they assert against known values, e.g. a draft page that must never
show).
Testing
dotnet test — 31 tests green (route smoke tests, nav builder, client tests).
Verified end to end on a fresh volume: the app renders real PocketBase content,
navigation is built from the records, and post detail pages show their body.
## What this does
The site now reads all its content from PocketBase over HTTP, one read per
request. The old file-based content layer (Markdown + YAML in `Content/`) is
gone. Closes #8.
## Main changes
- **Pages, posts, events and FAQs come from PocketBase.** A typed
`PocketBaseClient` (registered with `AddHttpClient`) reads each collection per
request. No content is cached at startup and no `FileSystemWatcher` is needed —
an editorial change is live right away.
- **Generic page rendering.** One `ContentPage` (`@page "/{Slug}"`) renders any
`pages` record, so a new page is just a new record — no `.razor` change. Literal
routes (`/posts`, `/events`, `/faqs`, `/`) still win over the catch-all.
- **Navigation is generated from the `pages` records** (header/footer, ordered),
not hard-coded. Pages can also opt into embedded lists (posts/events/faqs) via
an `embed` field.
- **English routes:** `/beitraege` → `/posts`, `/termine` → `/events`,
`/termine.ics` → `/events.ics`.
- **Removed the dead file content layer** (`Content/`, the reader, and the
`YamlDotNet` dependency).
- **Docs aligned** with the PocketBase reality (`architektur.md` AE-2/AE-3,
`CLAUDE.md`, `redaktion.md`, `entwicklung.md`, `recht.md`). Legal-text slugs are
now English (`imprint`, `privacy`).
## Developer experience
- **A fresh dev volume comes up populated.** A dev-only PocketBase migration
creates the collections and inserts example content on the first
`docker compose up`. It is idempotent, mounted only by `compose.dev.yaml`, and
never runs against production or the tests.
- **The collection schema has one source.** The dev seed and the test fixture
both read the same `pb/pb_migrations/collections_schema.json`, so the schema
can't drift between them. The test *records* stay fixed in the fixture on
purpose (they assert against known values, e.g. a draft page that must never
show).
## Testing
- `dotnet test` — 31 tests green (route smoke tests, nav builder, client tests).
- Verified end to end on a fresh volume: the app renders real PocketBase content,
navigation is built from the records, and post detail pages show their body.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What this does
The site now reads all its content from PocketBase over HTTP, one read per
request. The old file-based content layer (Markdown + YAML in
Content/) isgone. Closes #8.
Main changes
PocketBaseClient(registered withAddHttpClient) reads each collection perrequest. No content is cached at startup and no
FileSystemWatcheris needed —an editorial change is live right away.
ContentPage(@page "/{Slug}") renders anypagesrecord, so a new page is just a new record — no.razorchange. Literalroutes (
/posts,/events,/faqs,/) still win over the catch-all.pagesrecords (header/footer, ordered),not hard-coded. Pages can also opt into embedded lists (posts/events/faqs) via
an
embedfield./beitraege→/posts,/termine→/events,/termine.ics→/events.ics.Content/, the reader, and theYamlDotNetdependency).architektur.mdAE-2/AE-3,CLAUDE.md,redaktion.md,entwicklung.md,recht.md). Legal-text slugs arenow English (
imprint,privacy).Developer experience
creates the collections and inserts example content on the first
docker compose up. It is idempotent, mounted only bycompose.dev.yaml, andnever runs against production or the tests.
both read the same
pb/pb_migrations/collections_schema.json, so the schemacan't drift between them. The test records stay fixed in the fixture on
purpose (they assert against known values, e.g. a draft page that must never
show).
Testing
dotnet test— 31 tests green (route smoke tests, nav builder, client tests).navigation is built from the records, and post detail pages show their body.