Background
The dismissible announcement banner shipped as site-wide only — a single announcement (plus optional announcement_expires) theme option rendered at the top of every page. See the Announcement Banner docs.
The renderer was deliberately built to be additive: the template loops over a list of notices, announcement.js evaluates each .qe-announcement row independently (its own content-hash dismissal + its own expiry), and the dismissed-set in localStorage already tracks multiple IDs. So the JS, persistence, and most of the CSS already support N rows. What's left for per-page is the config plumbing, a little stacking polish, and one design decision.
Goal
Let an individual page carry its own announcement that stacks additively with the global one: global on top, page-specific below. Example use case — flagging that a single lecture now uses a newer library version (pandas==3.0) while a site-wide notice (an Anaconda upgrade) stays visible.
Open decision: how should a per-page notice be authored?
| Mechanism |
Pros |
Cons |
Config keyed by docname (an announcements: map in html_theme_options) |
Everything in one place; easy to audit and remove stale notices; non-authors can add one without touching lecture files |
Becomes public theme-option API (hard to change later); brittle to page renames; page content lives far from the page |
| MyST frontmatter on the page |
Co-located with the content; survives renames; natural fit for "this lecture uses …" |
Spread across many files; harder to get a site-wide overview |
My current lean is to re-evaluate frontmatter for per-page, since page-specific content arguably belongs with the page — but this is the thing to settle before building.
Settled design (for whichever mechanism wins)
- Additive: when both global and per-page are present, render two stacked rows (global first).
- Each row independent: its own expiry, its own
× dismiss, its own content-hash so editing one re-shows only that one.
- When a page has only one of the two, show just that one; when all rows are dismissed/expired, the bar collapses.
Scope / priority
Demand-driven — open this when there's a concrete need. The site-wide banner already covers the primary case.
Background
The dismissible announcement banner shipped as site-wide only — a single
announcement(plus optionalannouncement_expires) theme option rendered at the top of every page. See the Announcement Banner docs.The renderer was deliberately built to be additive: the template loops over a list of notices,
announcement.jsevaluates each.qe-announcementrow independently (its own content-hash dismissal + its own expiry), and the dismissed-set inlocalStoragealready tracks multiple IDs. So the JS, persistence, and most of the CSS already support N rows. What's left for per-page is the config plumbing, a little stacking polish, and one design decision.Goal
Let an individual page carry its own announcement that stacks additively with the global one: global on top, page-specific below. Example use case — flagging that a single lecture now uses a newer library version (
pandas==3.0) while a site-wide notice (an Anaconda upgrade) stays visible.Open decision: how should a per-page notice be authored?
announcements:map inhtml_theme_options)My current lean is to re-evaluate frontmatter for per-page, since page-specific content arguably belongs with the page — but this is the thing to settle before building.
Settled design (for whichever mechanism wins)
×dismiss, its own content-hash so editing one re-shows only that one.Scope / priority
Demand-driven — open this when there's a concrete need. The site-wide banner already covers the primary case.