Commit Graph
116 Commits
Author SHA1 Message Date
LeoVasanko 4a84aceb4f Add selectable site theme, custom CSS, and new font set
- Data.theme/Data.custom_css site settings with /_api/settings support;
  theme stylesheet linked per page, custom CSS inline as #pagerite-user,
  swapped during fetch-navigation
- Site editor: theme selector, custom CSS CodeMirror field; in-place
  stylesheet swap (diff-based, preserves editor stylesheets); dev swaps
  Vite-injected style tags since no <link>s exist there
- Dev theme delivery via <meta name="pagerite:theme"> + dynamic import
  in pagerite.js instead of a hardcoded purple import
- Fix dead edit pens in prod: Vite app builds strip entry exports, so
  the dynamic-imported main.js had no openEditor/closeEditor; build with
  preserveEntrySignatures 'exports-only' and log editor load failures
  instead of swallowing them
- Editor slide-in is one-shot: cleared on animationend so stylesheet
  swaps cannot restart a finished animation
- Replace Fraunces/Literata with Source Sans 3/Serif 4, Inter and
  Montserrat variable fonts; font stacks as CSS variables
2026-08-16 23:39:11 +00:00
LeoVasanko 8aa5d3d4a6 Move banner image to purple theme. 2026-08-16 22:28:51 +00:00
LeoVasanko b736fbd23f Updated ignores, remove lockfiles. 2026-08-16 20:25:21 +00:00
LeoVasanko f9ab44ae3f Update uv.lock for hatch-vcs dynamic versioning 2026-08-16 20:22:38 +00:00
LeoVasanko a7e5c40e12 Use git tag versioning via hatch-vcs
- Remove static version from [project]; add dynamic = [version]
- Add [tool.hatch.version] source = vcs
- Add hatch-vcs to build-system requirements
2026-08-16 20:22:00 +00:00
LeoVasanko 658dea77b9 Remove stale /_admin app and disable SPA fallback
- Remove the /_admin route, views.render_editor, and standalone mode from
  the Vue editor (main.js / PageEditor.vue)
- Remove /_admin dev proxy and preload exclusion
- Set vite appType to 'mpa' and delete frontend/index.html so unknown
  /_ paths return 404 instead of an empty Vue shell
- Update AGENTS.md and docs/design-principles.md
2026-08-16 20:20:19 +00:00
LeoVasanko 53d98f0583 Restructure internal URL prefixes from /_/... to /_...
- Move API routes from /_/api/ to /_api/
- Move uploaded files from /_/f/ to /_f/
- Move built assets from /_/assets/ to /_assets/
- Move admin shell from /_/admin to /_admin
- Update Vite proxy/build config, frontend fetches/WebSockets, devserver health URL, seed content, and docs
- Fix README database name to pagerite.kantadb
2026-08-16 20:04:16 +00:00
LeoVasanko 6de0307856 Split CSS into base and theme, link them separately
- Move shared structural styles to frontend/src/assets/pagerite.css
  with conservative variables, and purple theme overrides to
  frontend/src/assets/themes/purple/theme.css.
- Backend now links the base and theme stylesheets as separate files
  so they can be swapped or augmented.
- Add blocking="render" to stylesheet links to avoid FOUC.
- Drop redundant defer from module script tags.
- Update related docs and comments.
2026-08-16 19:51:17 +00:00
LeoVasanko 840f15ee59 Use location.replace when the standalone page editor saves and closes
Avoids leaving the /_/admin shell in the browser history stack.
2026-08-16 19:10:52 +00:00
LeoVasanko a8cf5a6a82 Rework category labels, slug validation, and task-list checkboxes
- Remove the section-header  "add landing page" button; landing pages are
  now created via the page editor pen.
- Treat saving a page with empty (after stripping) Markdown as deleting it:
  childless nodes are removed, nodes with children become content-less labels.
- Restrict server-side slugs to [a-z0-9_-] with no leading underscore or dot;
  drop the reserved-filename blacklist.
- Render placeholder pages for content-less category labels and link them to
  their first published child in the navigation.
- Make task-list checkboxes live, non-disabled inputs: toggling updates the
  Markdown source, updates the open CodeMirror document when the page editor is
  open, and persists to the server when no editor is open. Errors revert the UI.
- Update docs and AGENTS.md conventions accordingly.
2026-08-16 19:04:55 +00:00
LeoVasanko 3dc438f8df Fix structure tree drag feedback: stable rows, on-row child drops
Rework the site structure tree's drag-and-drop to match Sortable's native
model instead of mid-drag drop zones:

- Drop the dashed empty-list drop zones that appeared on drag start
  (flicker, space reservation, and mis-targeted drops: the last item's
  child zone sat exactly where 'end of parent list' was).
- Every non-empty list (and the root) ends with a non-draggable  footer
  row (vuedraggable #footer slot): click to start a new page at that
  level, and while dragging it is the 'end of this list' drop target.
  It renders last even mid-drag via flex order, since Sortable appends
  end-of-list previews after it in the DOM.
- Dropping ON the lower part of a row makes the page that row's first
  child: the child list's container invisibly overlaps its own row's
  bottom (negative margin + equal padding, no layout effect) and becomes
  hit-testable only while dragging. A row's exposed top strip remains
  the 'sibling before' target. Leaf rows work too, creating a sublist.
- Indentation is structural (each nested list margin-indents itself), so
  a dragged row previews its whole subtree at the target list's depth.
  Rows get a little vertical padding to widen the drop zones.
2026-08-16 18:05:33 +00:00
LeoVasanko e38063a522 Slug input filtering, title-derived slugs, reserved file names
Slug inputs in the site editor now filter as you type via slugify.js
(built on the transliteration npm package: unicode incl. asian scripts
folds to ASCII, spaces become hyphens, anything outside [a-z0-9-] is
dropped) instead of erroring on commit. A new page left with an empty
slug gets one derived from its title. Server-side, _check_reserved
additionally rejects reserved root file names (robots.txt, ads.txt,
sitemap.xml, openapi.json, favicon.ico, site.webmanifest) with a
human-readable reason, which the editor surfaces in its error line so
the row can be edited and committed again; those URLs are also never
looked up as content when serving.
2026-08-16 16:45:57 +00:00
LeoVasanko 37af433704 Reserve slugs beginning with _ or .
Enforced at three layers: the site editor validates slug inputs before
committing (rename and new-page rows), the API rejects such paths in
_check_reserved (page save/delete, structure moves, editor socket), and
the content catch-all 404s them without a tree lookup.
2026-08-16 16:25:26 +00:00
LeoVasanko 508795437f Mirror the URL space in the frontend build layout
Build with assetsDir: '_/assets' so hashed assets land under
frontend-build/_/assets/ and favicon.ico (from frontend/public) at the
build root, then serve the whole build directory at the site root again
(frontend.route(app, "/"), cached="/_/assets/"). The explicit
favicon route is dropped — the Frontend serves it as an ordinary
unhashed (no-cache) file. Manifest paths now carry the _/assets/
prefix, so views.py only prepends a slash.
2026-08-16 16:22:39 +00:00
LeoVasanko d5e40fba12 Serve built assets under /_/assets, admin at /_/admin
Reorganize the URL space so all machinery lives under /_/: the Vite
build (now with assetsDir: '', two ES-module entries and hashed shared
assets: style.css, pygments.css, banner.svg, fonts moved from
pagerite/static to frontend/src/assets) is served at /_/assets via
frontend.route(app, "/_/assets") with cached="/", and the admin
shell moves to /_/admin, leaving only "_" as a reserved top-level
slug. A /favicon.ico route serves the file Vite copies from
frontend/public. In dev, Vite proxies content pages and /_/admin to
the backend.

Editor changes: drop the noisy status line for a save-error indicator,
reconnect the WebSocket with exponential backoff, and re-establish the
connection from send() when it has dropped. The socket connects when
an editor is opened (they mount on pen click), not before.
2026-08-16 16:13:12 +00:00
LeoVasanko 36b250a15c Pagerite: single-user CMS/blog
FastAPI backend rendering HTML with html5tagger, content persisted in a
kanta database and rendered per request. Vue only for the editing tools
(page editor over a WebSocket, site/structure editor); public pages are
plain HTML with fetch navigation. No auth: single trusted author.
2026-08-16 05:49:38 +00:00