From 9742ccced1eb9a8bb04ec2e2ad33453ec2abce60 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sun, 4 Oct 2026 12:23:09 -0700 Subject: [PATCH] render {static} in Markdown alternatives Opus 5.5 spotted this when previous Claudes didn't Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 2 +- pelicanconf.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5f5d826..beeb69f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -285,7 +285,7 @@ Two related wants, neither implemented: a "Discussion on Less Wrong" link on eac **Where the LW URL should live — leaning sidecar, undecided.** The obvious answer is a `Lesswrong:` line in the post header; Pelican supports arbitrary metadata with no config change (`readers.py:320` lowercases the key, `:341` returns a single-line value as a string, `:117` passes unknown names through), exposing `article.lesswrong`. The problem is sequencing: the LW URL doesn't exist until *after* publishing, so post-header metadata forces a second commit per post that touches the post file. A sidecar `slug → LW URL` JSON keeps the publish commit clean and lets updates batch — which matters beyond tidiness, since every push triggers a full rebuild and the site-wide 404 window described above. Read it once in `pelicanconf.py` and attach `article.lesswrong` the way `_prepare_markdown_mirrors` attaches `article.markdown_url`; warn on a key matching no post, since the sidecar loses the typo-safety of co-located metadata. Slugs are verified unique corpus-wide, so slug is a safe key. Third option: linkpost *before* pushing (the blog URL is predictable from date and filename), publish once with the field already filled — costs a window where the LW post points at a 404. -**Gotcha either way:** `_write_markdown_mirrors` restates a **hardcoded** field list (Author, date, Category, Tags, Canonical URL), so a new field silently vanishes from the `.md` mirrors — i.e. the artifact that exists for LLM legibility — unless added there too. It also pipes the body through `_absolutize_site_links`, so anything else that reuses post bodies for off-site consumption wants the same treatment. +**Gotcha either way:** `_write_markdown_mirrors` restates a **hardcoded** field list (Author, date, Category, Tags, Canonical URL), so a new field silently vanishes from the `.md` mirrors — i.e. the artifact that exists for LLM legibility — unless added there too. It also pipes the body through `_resolve_static_links` (Pelican only resolves `{static}` in the HTML it renders, not in raw source) and `_absolutize_site_links`, so anything else that reuses post bodies for off-site consumption wants the same treatment. **Link-rewriting script.** Key on slug, not whole-URL matching. Since 2026-08-07 the corpus is uniform — every internal link is root-relative `/blog/YYYY/Mon/slug/` (293 of them: 287 in published posts, 6 in drafts), with no absolute or legacy-numeric-month forms left, so the script only has one input shape to parse. Dispositions: mapped post → LW URL; unmapped post → absolutize; link with a `#fragment` → leave pointing home, since LW has no corresponding anchor and a wrong landing spot beats an off-site one; `/blog/` and `/blog/tag/...` → absolutize only; plus a self-link guard. diff --git a/pelicanconf.py b/pelicanconf.py index 088f56d..bfc2b99 100644 --- a/pelicanconf.py +++ b/pelicanconf.py @@ -171,6 +171,21 @@ def _absolutize_site_links(body): lambda m: m.group(1) + origin + m.group(2) + m.group(3), body) +# Pelican rewrites {static}/path placeholders only in the HTML it renders; the +# mirrors are copied from the raw source, so without this they'd carry the +# literal placeholder. Resolve it the way Pelican does under the default +# STATIC_URL = '{path}': SITEURL + '/' + path, which is absolute in a publish +# build and root-relative ('/images/...') in a local one. Matches anywhere, +# not just in ](...) -- raw-HTML , ,