• v0.1.0 dd3efe870e

    v0.1.0 Stable

    petrbalvin released this 2026-06-21 11:15:06 +00:00 | 62 commits to main since this release

    First public release: a small, file-based Markdown blog engine in CRuby. Posts
    are plain files, the engine exposes them as a JSON API and ships a self-hosted
    admin — no database, no external services.

    Added

    Content & storage

    • File-based store: each post is a .md file with a TOML frontmatter block
      delimited by +++. No database.
    • Post fields: title, slug, date, lang, author, tags, draft,
      excerpt, cover, all_langs, and translations (a lang → slug map).
    • Drafts (draft = true) are hidden from the public API.
    • Excerpt falls back to the first paragraph (~200 chars) when none is set.
    • Estimated reading time (~200 words/min) computed per post.
    • Multilingual posts: per-language slugs via translations, plus all_langs
      to surface a single post under every language.

    Markdown rendering

    • GFM rendering via kramdown: tables, fenced code blocks, task lists, and
      strikethrough.
    • Automatic heading IDs for in-page anchors.
    • Raw HTML in post bodies is passed through (authors are the trusted admin).

    Public JSON API (/api/volumen)

    • Read-only endpoints: site, posts, posts/{slug}, tags, feed.xml
      (RSS), and sitemap.xml.
    • posts supports pagination (page, limit, returning total and
      page_size) and filtering by lang and tag.
    • Permissive CORS so a separate front end can consume the API.

    Admin (/admin)

    • Server-rendered admin with a sidebar layout and full post CRUD.
    • Dual-mode editor: Markdown source (primary) and a visual WYSIWYG, switchable
      per post, with a toggleable live preview persisted across sessions.
    • Image upload from the editor toolbar into content_dir/media; any image
      format is accepted (WebP and AVIF included) and served with the correct
      Content-Type.
    • Cover image field with upload, URL, clear, and preview.

    Multi-user & roles

    • Multiple admin users stored in users.toml, managed from a settings page.
    • Two roles: admin (full access incl. user management) and author (posts
      only).
    • Change password and username; last-admin and self-deletion safeguards.

    Configuration & CLI

    • TOML configuration, auto-generated with a commented template on first run.
    • Configurable host/port (defaults to 9090), content_dir,
      users_file, and site metadata.
    • CLI: serve, hash-password, version, help, with --config,
      --content, --host, and --port overrides.

    Deployment

    • install.sh installs the Ruby toolchain from distro packages on Fedora and
      openEuler (and prints guidance on other distros), creates the service user
      and directories, and installs a systemd unit.
    • Deployment docs for systemd and FreeBSD (rc.d), plus an nginx reverse-proxy
      setup that runs the admin same-origin, with brute-force rate-limiting and an
      optional IP allowlist on the login endpoint.

    Project & tooling

    • Documentation set: architecture, configuration, API reference, deployment,
      and security.
    • just task set (install, run, dev, build, test, uninstall) and
      Forgejo Actions CI (RuboCop + tests on Ruby 3.3/3.4, gem build on release).
    • CONTRIBUTING.md and a minitest suite; clean RuboCop.

    Security

    • Passwords hashed with scrypt and verified in constant time.
    • Per-form CSRF tokens on every state-changing admin request.
    • Session cookies are HttpOnly and SameSite=Strict, and gain the Secure
      attribute automatically on HTTPS requests (detected via request.ssl? /
      X-Forwarded-Proto), so the cookie never travels over plain HTTP in
      production.
    • Configurable, stable session_key so sessions survive restarts.
    • Generic login error message to avoid username enumeration.
    Downloads