← back to Crazy News Channel
cartoon pages: share one page template between approve.py and the Shadow Man export (TK-12247)
afee2fe2932db3c017760cfdf35bf08a2480a49e · 2026-09-25 11:43:10 -0700 · Steve
approve.py now renders cartoons/<date>-<slug>.html from daily-cartoons/cartoon-page.template.html;
output verified byte-identical to the previous inline f-string on a scratch copy.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XizSgLiFuNbjY418z94Ewq
Files touched
M daily-cartoons/approve.pyA daily-cartoons/cartoon-page.template.html
Diff
commit afee2fe2932db3c017760cfdf35bf08a2480a49e
Author: Steve <steve@designerwallcoverings.com>
Date: Fri Sep 25 11:43:10 2026 -0700
cartoon pages: share one page template between approve.py and the Shadow Man export (TK-12247)
approve.py now renders cartoons/<date>-<slug>.html from daily-cartoons/cartoon-page.template.html;
output verified byte-identical to the previous inline f-string on a scratch copy.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XizSgLiFuNbjY418z94Ewq
---
daily-cartoons/approve.py | 18 +++++++++++++-----
daily-cartoons/cartoon-page.template.html | 5 +++++
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/daily-cartoons/approve.py b/daily-cartoons/approve.py
index f13bd8b..8b6f49b 100755
--- a/daily-cartoons/approve.py
+++ b/daily-cartoons/approve.py
@@ -16,6 +16,14 @@ import build_review
CART = os.path.join(C.SITE, "cartoons")
+TEMPLATE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cartoon-page.template.html")
+
+def render_page(**fields):
+ """Fill cartoon-page.template.html ({{key}} placeholders, single pass). Values must already be
+ HTML-escaped (media/source are pre-built markup)."""
+ tpl = open(TEMPLATE, encoding="utf-8").read().rstrip("\n")
+ return re.sub(r"\{\{(\w+)\}\}", lambda mo: fields[mo.group(1)], tpl)
+
def story_exists(sid):
for f in ("stories-data.js", "real-news-data.js"):
p = os.path.join(C.SITE, f)
@@ -53,11 +61,11 @@ def main():
src_url, src_title = m.get("story_url"), m.get("story_title")
src_html = (f'<p class="src"><a href="{e(src_url)}" target="_blank" rel="noopener noreferrer">Source: {e(src_title or "linked article")}</a></p>'
if src_url else "")
- open(os.path.join(CART, base + ".html"), "w").write(f'''<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
-<meta name="viewport" content="width=device-width,initial-scale=1"><title>{e(m["title"])}</title>
-<link rel="stylesheet" href="../assets/style.css"></head>
-<body class="cartoon-page-simple"><p><a href="index.html">← Cartoon Desk</a></p>{media}<h1>{e(m["title"])}</h1>
-<p class="cap">“{e(m["caption"])}”</p>{src_html}<p><small>AI-generated editorial cartoon in classic editorial-ink style. Invented figures only.</small></p></body></html>''')
+ # TK-12247: the page markup lives in daily-cartoons/cartoon-page.template.html, shared with the
+ # Inkwell Shadow Man export so every single-image cartoon page is rendered from ONE template.
+ open(os.path.join(CART, base + ".html"), "w").write(render_page(
+ title=e(m["title"]), media=media, caption=e(m["caption"]), source=src_html,
+ credit="AI-generated editorial cartoon in classic editorial-ink style. Invented figures only."))
mf = os.path.join(CART, "manifest.js"); src = open(mf).read()
mm = re.search(r"(window\.P24_CARTOONS\s*=\s*)(\[[\s\S]*\])(\s*;\s*)$", src)
arr = json.loads(mm.group(2)); arr = [x for x in arr if x.get("id") != a.slug]
diff --git a/daily-cartoons/cartoon-page.template.html b/daily-cartoons/cartoon-page.template.html
new file mode 100644
index 0000000..e781f84
--- /dev/null
+++ b/daily-cartoons/cartoon-page.template.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
+<meta name="viewport" content="width=device-width,initial-scale=1"><title>{{title}}</title>
+<link rel="stylesheet" href="../assets/style.css"></head>
+<body class="cartoon-page-simple"><p><a href="index.html">← Cartoon Desk</a></p>{{media}}<h1>{{title}}</h1>
+<p class="cap">“{{caption}}”</p>{{source}}<p><small>{{credit}}</small></p></body></html>
\ No newline at end of file
← 95c7f77 auto-data-snapshot: 2026-09-25T11:23:40 (3 data files) — .cl
·
back to Crazy News Channel
·
p24: attach 2 Shadow Man cartoons to their articles — Money b0563b7 →