• v0.3.0 6f62d3e3f3

    v0.3.0 Stable

    petrbalvin released this 2026-07-12 12:03:22 +00:00 | 12 commits to main since this release

    Added

    Content & authoring

    • Fediverse attribution: a fediverse_creator frontmatter field (e.g.
      @user@mastodon.social) plus a site-wide [site].fediverse_creator default
      in config.toml. The value is exposed as fediverse_creator on the site
      and post payloads, rendered as <dc:creator> in the RSS feed, as
      authors[].name in the JSON feed, and can be consumed by a front-end to
      emit <meta name="fediverse:creator"> on rendered pages. Per-post values
      override the site default.
    • Cover caption: a cover_caption post field rendered next to the cover
      image so authors can credit photos or add a short blurb.
    • Titled images as <figure>: Markdown images with a title
      (![alt](url "caption")) are wrapped in a <figure> with a <figcaption>
      and a small i info icon. Images without a title render exactly as before.

    Public API

    • has_next and has_prev boolean flags in the paginated
      /api/volumen/posts response so clients can navigate pages without
      computing boundaries themselves.
    • Distinct "draft" error code in /api/volumen/posts/:slug when the post
      exists but is a draft, replacing the generic "not_found".

    Admin

    • Modern admin UI: redesigned layout with a sticky top bar, breadcrumbs
      on every page, and a unified design language across login, post list,
      post form, and settings.
    • Volumen icon: a dedicated SVG icon shown in the sidebar and on the
      login page (served at /admin/icon.svg).
    • Version in sidebar footer so admins always see which release is
      running.
    • Per-user display name on the user record and admin header.
    • Per-user fediverse handle editable from the settings page (independent
      of the post-level fediverse_creator).
    • Profile photo upload: each admin user can upload a WebP/AVIF avatar
      that is stored alongside posts in the content directory and shown in the
      settings page.
    • Tabbed settings page separating account, profile, and admin sections.
    • Restricted uploads: only WebP (image/webp) and AVIF (image/avif)
      are accepted, with a 415 error message that points users to cwebp /
      avifenc for conversion. Reflects the engine's WebP/AVIF-only posture
      end-to-end.
    • Polished native inputs for <input type="date|time|file"> so they
      match the rest of the admin's design language.

    Tooling

    • just lint recipe for standalone RuboCop checks and just fmt for
      auto-fixing lint issues.
    • config.toml.example template for local development; config.toml is
      now gitignored.

    Changed

    • Memoize published_posts within a single request so repeated calls
      (posts list, tags, feeds, sitemap) reuse the cached result.
    • Store#all cache now invalidates on individual file mtime changes, not
      just on the content directory mtime. Manual edits and git pull are
      detected without a restart.
    • Cache-Control: public, max-age=60 header on all public API responses
      for browser and CDN caching.
    • Extract feed and sitemap generation into a dedicated FeedHelpers module,
      reducing Server from ~500 to ~420 lines.

    Fixed

    • Admin post save/delete now correctly clears the in-memory posts cache, so
      the post list reflects edits without a manual reload.
    • The post form's date field defaults to today when the underlying post has
      no date, preventing the picker from showing an invalid empty value.

    Security

    • Content-Security-Policy header on all /admin/* responses:
      default-src 'self', script-src 'self' 'unsafe-inline',
      style-src 'self' 'unsafe-inline', img-src 'self' data:,
      font-src 'self', connect-src 'self', form-action 'self',
      frame-ancestors 'none'.
    • File uploads are rejected (HTTP 413) when exceeding 10 MB
      (MAX_UPLOAD_BYTES).
    • File uploads are restricted to image/webp and image/avif
      (ALLOWED_UPLOAD_TYPES). Anything else is rejected with a 415 and a
      conversion hint.
    Downloads