From 372b81b4ab5fb7dff9c9a91508ec14e8bdf0dab4 Mon Sep 17 00:00:00 2001 From: lcy-seso Date: Fri, 2 Oct 2026 13:17:30 +0800 Subject: [PATCH] [Docs] Version the stylesheet URL by its content GitHub Pages serves assets/extra.css under the same URL whatever it contains, so a browser that cached an older copy keeps it and renders new markup without the styles that go with it: the User Guide cards showed as plain headings and lists. hooks.py now appends a hash of the stylesheet's content to its URL, so the URL changes whenever the styles do. --- CLAUDE.md | 3 +++ hooks.py | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 30d0e675..0a4929be 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -138,5 +138,8 @@ renders no post under `mkdocs-static-i18n` and warns on its archive pages. arrow, east within the site and north-east off it, and a teal wash on hover. - Link to the TileOPs repo rather than duplicating it. A page authored here that mirrors upstream content will drift. +- `hooks.py` appends a content hash to each local `extra_css` URL, so a changed + stylesheet reaches readers whose browser cached the old one. Do not add a + `?v=` by hand. - Gitignored: `site/`, `__pycache__/`, `.cache/`, `TileOPs/`, and `docs/benchmarks/` except `index.md`. diff --git a/hooks.py b/hooks.py index 9b7b7ded..2bb6c437 100644 --- a/hooks.py +++ b/hooks.py @@ -16,9 +16,12 @@ marks those lists for extra.css, which draws each item as a card. * A page merged into another leaves its old URL behind; `on_post_build` writes a redirect there, so published links keep working. +* The stylesheet's URL carries a hash of its content, set in `on_config`, so a + browser holding an older copy fetches the new one as soon as it changes. """ from __future__ import annotations +import hashlib import os import re @@ -81,8 +84,23 @@ def on_page_markdown(markdown, page, config, files): ] +def _bust_css_cache(config): + """Append `?v=` to each local stylesheet in `extra_css`.""" + out = [] + for entry in config["extra_css"]: + path = os.path.join(config["docs_dir"], str(entry)) + if "?" in str(entry) or not os.path.isfile(path): + out.append(entry) + continue + with open(path, "rb") as f: + digest = hashlib.sha256(f.read()).hexdigest()[:10] + out.append(f"{entry}?v={digest}") + config["extra_css"] = out + + def on_config(config): - """Expand the Benchmarks nav entry to the generated pages.""" + """Version the stylesheet URL; expand the Benchmarks nav entry.""" + _bust_css_cache(config) bench_dir = os.path.join(config["docs_dir"], "benchmarks") if not os.path.isdir(bench_dir): return config