Soapbox: statisk blogg med mobilvennlig markdown-editor
Flask-app som genererer statiske sider til public/ og serverer dem sammen med et admin-grensesnitt (/admin). Innhold ligger som markdown og bilder i et git-repo (data/content), brukere i sqlite. - Editor med toolbar, live server-side forhåndsvisning, bildeopplasting via knapp, dra-og-slipp og lim inn. Bilder nedskaleres og EXIF fjernes. - Hovedbruker publiserer under /<slug>/, gjester under /<bruker>/<slug>/. Slug lages fra tittelen og fryses ved publisering. - Alle interne lenker er relative, så siden kan flyttes mellom domener og sub-paths (SOAPBOX_BASE_PATH) uten rebuild. - Tema 'green' med CSS-variabler, mørk modus og WCAG-kontrast. - Containerfile (python:alpine + git), compose.yaml og Caddyfile-eksempel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JcEy43fNYpwg6K6oTKakWR
This commit is contained in:
commit
7ab2320be6
35 changed files with 2726 additions and 0 deletions
81
README.md
Normal file
81
README.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Soapbox
|
||||
|
||||
En liten blogg: statiske sider, mobilvennlig Markdown-editor med bildeopplasting og live
|
||||
forhåndsvisning, innhold versjonert i git. Én hovedbruker («soapbox») pluss valgfrie gjester.
|
||||
|
||||
## Hvordan det henger sammen
|
||||
|
||||
```
|
||||
data/
|
||||
├── content/ git-repo – alt innhold, kan klones/flyttes fritt
|
||||
│ ├── site.toml tittel, beskrivelse, språk
|
||||
│ ├── posts/<slug>/index.md + bilder → /<slug>/
|
||||
│ └── guests/<bruker>/<slug>/index.md → /<bruker>/<slug>/
|
||||
├── public/ generert statisk side (bygges automatisk ved lagring)
|
||||
├── soapbox.sqlite brukere og passord-hasher – det eneste som ikke ligger i git
|
||||
└── secret_key cookie-signering (genereres automatisk)
|
||||
```
|
||||
|
||||
* **Slug** lages av tittelen (`Grønt er skjønt` → `groent-er-skjoent`). Den følger tittelen så
|
||||
lenge innlegget er utkast, og fryses ved publisering så lenker aldri brekker.
|
||||
* **Alle interne lenker er relative.** Malene regner ut `../` ut fra sidens dybde, og absolutte
|
||||
lenker du skriver i Markdown (`/annet-innlegg/`) skrives om. Derfor fungerer samme `public/`
|
||||
både på `blog.domene.no/` og `annet-domene.com/blog/` uten rebuild.
|
||||
* **Bilder** ligger i samme mappe som innlegget og refereres som ``. Ved opplasting
|
||||
skaleres de ned (maks 2000 px) og EXIF fjernes (ingen GPS-posisjon publiseres).
|
||||
* **Hver lagring er en git-commit** med brukeren som forfatter. Se historikken under
|
||||
Innstillinger, eller `git -C data/content log`.
|
||||
* **Gjester** ser og redigerer bare egne innlegg. Hovedbrukeren ser alt og administrerer gjester.
|
||||
|
||||
## Kjøre lokalt
|
||||
|
||||
```sh
|
||||
uv sync
|
||||
SOAPBOX_DATA_DIR=./data uv run soapbox create-user olemd --role owner
|
||||
SOAPBOX_DATA_DIR=./data uv run soapbox serve --debug
|
||||
# → http://localhost:8080/admin/
|
||||
```
|
||||
|
||||
Tester: `uv run pytest`. Lint: `uv run ruff check . && uv run ruff format .`
|
||||
|
||||
## Konfigurasjon (miljøvariabler)
|
||||
|
||||
| Variabel | Standard | Beskrivelse |
|
||||
|---|---|---|
|
||||
| `SOAPBOX_DATA_DIR` | `./data` (`/data` i container) | Alt persistent |
|
||||
| `SOAPBOX_BASE_PATH` | `` | `/blog` hvis bloggen ligger under en sub-path |
|
||||
| `SOAPBOX_SITE_URL` | `http://localhost:8080` | Absolutt URL til rot, brukes **bare** i `feed.xml` |
|
||||
| `SOAPBOX_THEME` | `green` | Mappe under `soapbox/themes/` |
|
||||
| `SOAPBOX_MAX_IMAGE_PX` | `2000` | Lengste side på opplastede bilder |
|
||||
| `SOAPBOX_SECRET_KEY` | autogenerert | Overstyr hvis du vil ha nøkkelen utenfor volumet |
|
||||
| `SOAPBOX_OWNER_USER` / `_PASSWORD` | – | Oppretter hovedbruker ved første start |
|
||||
|
||||
## Container og Caddy
|
||||
|
||||
```sh
|
||||
BUILDAH_FORMAT=docker podman build \
|
||||
--build-arg BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--build-arg GIT_REVISION="$(git describe --always --dirty)" \
|
||||
-t soapbox .
|
||||
podman compose up -d # se compose.yaml
|
||||
```
|
||||
|
||||
Caddy er ren reverse proxy, se `Caddyfile.example`. Ved sub-path skal Caddy **ikke** strippe
|
||||
prefikset – appen monteres selv under `SOAPBOX_BASE_PATH`.
|
||||
|
||||
## Flytte bloggen (nytt domene og/eller sub-path)
|
||||
|
||||
1. Kopier `data/`-volumet (eller bare `git clone` `data/content` og opprett brukerne på nytt).
|
||||
2. Sett `SOAPBOX_SITE_URL` og eventuelt `SOAPBOX_BASE_PATH` til de nye verdiene.
|
||||
3. Start – siden bygges på nytt. Ingen innhold trenger endring.
|
||||
|
||||
## Tema
|
||||
|
||||
Et tema er en mappe under `soapbox/themes/<navn>/` med `templates/` (`base.html`, `index.html`,
|
||||
`post.html`) og `static/` (kopieres til `/theme/`). Enkleste tilpasning: kopier `green`, endre
|
||||
CSS-variablene øverst i `style.css`. Malene får `site`, `posts`/`post`, `html` og `rel(sti)`.
|
||||
|
||||
## Veien videre (ikke i denne omgangen)
|
||||
|
||||
* Poste lenker til fediverset/Bluesky og vise svar som kommentarer.
|
||||
* Push av innholdsrepoet til en ekstern git-remote.
|
||||
Loading…
Add table
Add a link
Reference in a new issue