- golem15_journal_image_variants (migration 202610280002): a thumbnail
per width of golem15.journal.image_widths (480, 800, 1200 by default,
never wider than the original) and its WebP copy, with the original's
size
- conga job golem15.journal.image_variants (three attempts), queued after
a featured image upload and after an admin save of a post whose images
lack a width; the upload request never encodes
- journal:image-variants [--all] backfills
- featured_images[].variants {width, height, url, webp_url, source_width,
source_height} on the post answers (additive key)
- golem15.journal.related_mode (category | scored, default category) and
golem15.journal.related_count (3 to 6, default 3, clamped) in
config/config.yaml; classes.ReadRelatedSettings reads them
- the default mode answers GET /posts/{slug} exactly as before
- scored: related posts ranked by 2 points per shared tag plus 1 per
shared category, ties by newest, in one scoring query
(classes.ScoredRelatedPosts), published only for visitors; the answer
adds previous_in_category and next_in_category, the neighbours by
publish time within the post's first category by name
(classes.CategoryNeighbour), in the direction of previous_post and
next_post
- TestRelatedDefaultUnchanged, TestRelatedScored (a draft and a future
post sharing every tag never shown) and TestRelatedScoredCountClamped
- content_h1_to_h2 and generic_anchors on the settings row (migration
202610280001), Headings and links tab, config key
golem15.journal.content_h1_to_h2 used when no settings row exists
- classes.ConvertH1 on the x/net/html tokenizer; the Blog Editor types
convert while the setting is on and answer editor.h1_converted
- GET /posts/{slug} reports content_h1_to_h2 (additive key)