v0.2.2
[0.2.2]
Added
-
Diagnostics: email and storage test actions. Admin → System →
Diagnostics' "Test services" panel now covers email (sends a real test
message through the configured transport to the site's admin address) and
storage (a write/read/delete round trip against the configured uploads
directory) alongside the existing database, cache, and jobs checks. The
server-host reproduction commands are now copyable with one click.
(#57) -
Built-in site search. Public
/searchpages and thecore.searchblock
support locale, type, taxonomy/date filters, relevance, highlighting, and
pagination. Admin content search uses a shared incremental database full-text
index with access scopes; Tools adds visibility settings and index rebuild.
The headless search API and documented plugin backend interface preserve
live publication checks, with rate limiting and opt-in anonymous metrics stored in the database (no console or file logging).
(#101) -
Automatic responsive images and modern formats. Raster uploads now
generate a configurable set of width-scaled variants plus WebP (and AVIF when
enabled) alongside the untouched original, inline on upload and backfillable
from a new Admin → Tools → Responsive images job with progress and
per-file failures. Every public surface that renders an uploaded image now
goes through one resolver —core.image, the Gallery block (grid,
masonry, carousel, slideshow, list, and lightbox), blog-post-list featured
thumbnails, and the Featured Image theme block — emitting<picture>/
srcset/sizeswith format fallback, intrinsicwidth/heightto prevent
layout shift, andloading="lazy"/decoding="async"defaults with an
eageropt-out (fetchpriority="high") for above-the-fold images; the
exportedrenderResponsiveImage/renderMediaImagehelpers give plugin and
theme blocks the same output. Each asset carries a focal point, set by
clicking the subject in the Media Library, that drives thumbnail crops and
object-position. Generation, a public-markup toggle
(JF_IMAGE_RESPONSIVE_MARKUP— serve originals everywhere without deleting
variants), AVIF, quality, widths, max dimension, EXIF/GPS stripping, thumbnail
size, and a keep-original filename allowlist are all configurable in the same
panel and written to.envasJF_IMAGE_*with no restart. SVGs are never
rasterised, variants live under the sameuploads/path so CDN/S3 offload and
static export cover them for free, and migration0027_media_responsive
supports all database dialects. Seedocs/MEDIA.md.
(#103) -
Headless federated management API. Revocable API keys (Admin → Settings →
API) authenticate a versioned/api/manage/v1surface that federates content
(CRUD, publish, revisions), media, comments, menus, content types, users,
roles, settings, languages, redirects, plugin/theme listing and activation,
cache and static-export triggers, and diagnostics/health behind the same
capability checks as the admin UI — no parallel business logic. Each key
carries an explicit capability set never broader than its creator's,
re-checked against the owner's current access on every request, plus optional
AccessScope, expiry, and allowed-IP / allowed-origin lists; the secret is
shown once and stored only as a hash with a visiblejfk_prefix. A master
switch and per-key / global rate limits apply without a restart, wildcard CORS
never reaches an authenticated route, and every create / rotate / revoke and
auth failure is audited by key id. Admin → Settings → API is now the single
home for both HTTP-API switches — the public-content API toggle moves here
from Admin → Settings.GET /api/manage/v1/eventspublishes the event catalog with payload
schemas, and a key withsettings:manageself-registers and manages its own
webhook endpoints. The full surface is described by abearerAuthOpenAPI 3.1
document atGET /api/manage/v1/openapi.json. Migration0026_api_keys
supports all database dialects.
(#135)
Fixed
- Unknown multi-segment public URLs (for example
/foo/bar) now render the
site's themed 404 — the theme'stemplates/404.jsonwhen it ships one,
otherwise the built-in Justflows 404 — instead of Express's bare
Cannot GET. Single-segment paths already did this; deep paths fell through
the public router.