8 Commits
Author SHA1 Message Date
LeoVasanko 399aa95d44 Encapsulate all migrations in kanta migrate_vN, drop persisted Data.version
migrate_v1 now also rebuilds the legacy flat pages store as the menu
tree (moved from the app lifespan, raw-dict level); migrate_v2 now also
backfills missing AVIF/WebP/JPEG derivatives on disk (moved from the
lifespan) and drops the obsolete version field. The version render
counter was cache-invalidation state, not database state: replaced by an
in-memory render generation that clears the page-body LRU and feeds page
ETags. The legacy Page struct and Data.pages/version fields are removed;
old databases lose the stale keys on re-serialization.
2026-08-29 20:16:13 +00:00
LeoVasanko f793d21c5e Serve images extension-less at /_f/{hash} with Accept-negotiated AVIF/WebP/JPEG
Uploaded images (SVGs rasterized, GIFs excepted) are stored as the
original (hash.orig.ext, internal only, never served) plus AVIF primary
and WebP/JPEG fallback derivatives re-encoded from it. Pages link the
bare hash; the server serves a format only when Accept lists it
explicitly (image/avif -> AVIF, image/webp -> WebP, else JPEG) with
vary: accept, while an explicit extension pins the format. Favicons go
through the same pipeline at 192px. migrate_v2 rewrites old
/_f/{hash}.avif article links, a startup backfill creates missing
derivatives, and twitter:image pins the .webp variant for X's scraper.
2026-08-29 19:46:47 +00:00
LeoVasanko 6058853341 Recompress uploaded images to thumbnailed AVIF via mediapreview
PUT /_api/files now runs raster uploads through mediapreview.dispatch
(temp file for format routing: pyvips, ffmpeg for HEIC/HEIF/AVIF),
storing the untouched original as <hash>.orig<ext> and serving the
AVIF derivative <hash>.avif in links. SVG/GIF and failed conversions
fall back to plain <hash><ext> storage. FileStore.delete removes the
whole hash pair. Adds mediapreview[standard] dependency.
2026-08-29 05:59:37 +00:00
LeoVasanko c801fdc929 Make the page transition configurable, add crossfade/slide/reveal
The cube view-transition block moves out of pagerite.css into transition
designs (pagerite/themes/{name}/transition.css), handled like banner
designs: served from disk at /_themes/..., injected by the backend as
#pagerite-transition after the banner sheet, and picked site-wide in the
site settings (Data.transition, default cube; GET/PUT /_api/settings
carry transition + the designs found on disk). The site editor swaps the
sheet in place on change; the dev-mode order fixup knows the new id.

Designs: cube (unchanged), crossfade (all navigations), slide (sideways,
both pages moving together) and reveal (clip-path wipe over the
stationary old page) — the latter two mirrored on history-back and
crossfading within a section like cube.

Also compress the site settings form into a two-column grid: site name +
favicon on one row, theme + transition on the next.
2026-08-28 20:04:21 +00:00
LeoVasanko 2060dc815c Per-hostname data directory <hostname>/{content.kantadb, analytics.json, files} from CLI arg; drop learned site_url.
The first positional CLI argument (default localhost) names the site's
public hostname and its data directory under the cwd, replacing the
CWD-relative pagerite.* files. The public origin (https://<hostname>)
is now authoritative configuration instead of a value learned from
admin browsers: POST /_api/site-url, Data.site_url and the pagerite.js
reporter are removed, and page rendering, sitemap, robots.txt and
analytics own_origin all use SITE_URL consistently (localhost falls
back to the request's base URL).
2026-08-28 14:57:04 +00:00
LeoVasanko ffa7200a6e Automatic navigational cards on index pages, replacing the sidebar menu. 2026-08-28 00:25:10 +00:00
LeoVasanko 319163ee7e Page caching and zstd compression. Avoid useless fetching. Mobile layouts of navigation menus improved. 2026-08-22 14:05:12 +00:00
LeoVasanko 81f08e7760 Updated docs 2026-08-19 16:11:42 +00:00