diff --git a/docs/user_guide/announcements.rst b/docs/user_guide/announcements.rst
index edac65ff9..2b48829aa 100644
--- a/docs/user_guide/announcements.rst
+++ b/docs/user_guide/announcements.rst
@@ -44,12 +44,20 @@ For example, the following configuration tells the theme to load the ``custom-te
Update or remove announcement banner
------------------------------------
-To update or remove the announcement banner, you can change the value of
-``html_theme_options["announcement"]`` in your ``conf.py`` or you can edit the
-contents of the ``custom-template.html`` file directly. For example, if you have a
-temporary announcement that you want to remove without rebuilding your
-documentation pages, you can use an empty ``custom-template.html`` file and the
-banner will be hidden.
+If you set ``html_theme_options["announcement"]`` to plain text or HTML, then to
+update the announcement banner you need to modify this string and rebuild your
+documentation pages. To remove the announcement banner, set this value to an
+empty string and rebuild your documentation pages.
+
+If you set ``html_theme_options["announcement"]`` to a URL string (starts with
+``http``), then you can edit the file at that URL to update the announcement
+banner. Saving an empty file at that URL will remove the announcement banner.
+That's the main advantage of using a URL--you can change the announcement banner
+without rebuilding and redeploying all of your documentation pages. For example,
+if you point the announcement to the URL of a file in your repo, as we do on
+this documentation site (see previous section), then you can edit, save and push
+your changes to just that file (empty file = remove announcement) without
+rebuilding and redeploying all your docs.
.. _version-warning-banners:
diff --git a/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js b/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js
index ccefaebee..dc5b44c6f 100644
--- a/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js
+++ b/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js
@@ -488,16 +488,13 @@ function showVersionWarningBanner(data) {
return;
}
// now construct the warning banner
- var outer = document.createElement("aside");
- // TODO: add to translatable strings
- outer.setAttribute("aria-label", "Version warning");
+ const banner = document.querySelector(".bd-header-version-warning");
const middle = document.createElement("div");
const inner = document.createElement("div");
const bold = document.createElement("strong");
const button = document.createElement("a");
// these classes exist since pydata-sphinx-theme v0.10.0
// the init class is used for animation
- outer.classList = "bd-header-version-warning container-fluid init";
middle.classList = "bd-header-announcement__content";
inner.classList = "sidebar-message";
button.classList =
@@ -522,35 +519,12 @@ function showVersionWarningBanner(data) {
} else {
bold.innerText = `version ${version}`;
}
- outer.appendChild(middle);
+ banner.appendChild(middle);
middle.appendChild(inner);
inner.appendChild(bold);
inner.appendChild(document.createTextNode("."));
inner.appendChild(button);
- const skipLink = document.getElementById("pst-skip-link");
- skipLink.after(outer);
- // At least 3rem height
- const autoHeight = Math.max(
- outer.offsetHeight,
- 3 * parseFloat(getComputedStyle(document.documentElement).fontSize),
- );
- // Set height and vertical padding to 0 to prepare the height transition
- outer.style.setProperty("height", 0);
- outer.style.setProperty("padding-top", 0);
- outer.style.setProperty("padding-bottom", 0);
- outer.classList.remove("init");
- // Set height to the computed height with a small timeout to activate the transition
- setTimeout(() => {
- outer.style.setProperty("height", `${autoHeight}px`);
- // Wait for a bit more than 300ms (the transition duration) then remove the
- // forcefully set styles and let CSS take over
- setTimeout(() => {
- outer.style.removeProperty("padding-top");
- outer.style.removeProperty("padding-bottom");
- outer.style.removeProperty("height");
- outer.style.setProperty("min-height", "3rem");
- }, 320);
- }, 10);
+ banner.classList.remove("d-none");
}
/*******************************************************************************
@@ -584,27 +558,29 @@ function initRTDObserver() {
observer.observe(document.body, config);
}
-// fetch the JSON version data (only once), then use it to populate the version
-// switcher and maybe show the version warning bar
-var versionSwitcherBtns = document.querySelectorAll(
- ".version-switcher__button",
-);
-const hasSwitcherMenu = versionSwitcherBtns.length > 0;
-const hasVersionsJSON = DOCUMENTATION_OPTIONS.hasOwnProperty(
- "theme_switcher_json_url",
-);
-const wantsWarningBanner = DOCUMENTATION_OPTIONS.show_version_warning_banner;
-
-if (hasVersionsJSON && (hasSwitcherMenu || wantsWarningBanner)) {
- const data = await fetchVersionSwitcherJSON(
- DOCUMENTATION_OPTIONS.theme_switcher_json_url,
+async function fetchAndUseVersions() {
+ // fetch the JSON version data (only once), then use it to populate the version
+ // switcher and maybe show the version warning bar
+ var versionSwitcherBtns = document.querySelectorAll(
+ ".version-switcher__button",
+ );
+ const hasSwitcherMenu = versionSwitcherBtns.length > 0;
+ const hasVersionsJSON = DOCUMENTATION_OPTIONS.hasOwnProperty(
+ "theme_switcher_json_url",
);
- // TODO: remove the `if(data)` once the `return null` is fixed within fetchVersionSwitcherJSON.
- // We don't really want the switcher and warning bar to silently not work.
- if (data) {
- populateVersionSwitcher(data, versionSwitcherBtns);
- if (wantsWarningBanner) {
- showVersionWarningBanner(data);
+ const wantsWarningBanner = DOCUMENTATION_OPTIONS.show_version_warning_banner;
+
+ if (hasVersionsJSON && (hasSwitcherMenu || wantsWarningBanner)) {
+ const data = await fetchVersionSwitcherJSON(
+ DOCUMENTATION_OPTIONS.theme_switcher_json_url,
+ );
+ // TODO: remove the `if(data)` once the `return null` is fixed within fetchVersionSwitcherJSON.
+ // We don't really want the switcher and warning bar to silently not work.
+ if (data) {
+ populateVersionSwitcher(data, versionSwitcherBtns);
+ if (wantsWarningBanner) {
+ showVersionWarningBanner(data);
+ }
}
}
}
@@ -718,10 +694,70 @@ function debounce(callback, wait) {
};
}
+/*******************************************************************************
+ * Announcement banner - fetch and load remote HTML
+ */
+async function setupAnnouncementBanner() {
+ const banner = document.querySelector(".bd-header-announcement");
+ const { pstAnnouncementUrl } = banner.dataset;
+
+ if (!pstAnnouncementUrl) {
+ return;
+ }
+
+ try {
+ const response = await fetch(pstAnnouncementUrl);
+ if (!response.ok) {
+ throw new Error(
+ `[PST]: HTTP response status not ok: ${response.status} ${response.statusText}`,
+ );
+ }
+ const data = await response.text();
+ if (data.length === 0) {
+ console.log(`[PST]: Empty announcement at: ${pstAnnouncementUrl}`);
+ return;
+ }
+ banner.innerHTML = `
`;
+ banner.classList.remove("d-none");
+ } catch (_error) {
+ console.log(`[PST]: Failed to load announcement at: ${pstAnnouncementUrl}`);
+ console.error(_error);
+ }
+}
+
+/*******************************************************************************
+ * Reveal (and animate) the banners (version warning, announcement) together
+ */
+async function fetchRevealBannersTogether() {
+ // Wait until finished fetching and loading banners
+ await Promise.allSettled([fetchAndUseVersions(), setupAnnouncementBanner()]);
+
+ // The revealer element should have CSS rules that set height to 0, overflow
+ // to hidden, and an animation transition on the height (unless the user has
+ // turned off animations)
+ const revealer = document.querySelector(".pst-async-banner-revealer");
+
+ // Remove the d-none (display-none) class to calculate the children heights.
+ revealer.classList.remove("d-none");
+
+ // Add together the heights of the element's children
+ const height = Array.from(revealer.children).reduce(
+ (height, el) => height + el.offsetHeight,
+ 0,
+ );
+
+ // Use the calculated height to give the revealer a non-zero height (if
+ // animations allowed, the height change will animate)
+ revealer.style.setProperty("height", `${height}px`);
+}
+
/*******************************************************************************
* Call functions after document loading.
*/
+// Call this one first to kick off the network request for the version warning
+// and announcement banner data as early as possible.
+documentReady(fetchRevealBannersTogether);
documentReady(addModeListener);
documentReady(scrollToActive);
documentReady(addTOCInteractivity);
diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss b/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss
index 8fbc50b3c..331014be3 100644
--- a/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss
+++ b/src/pydata_sphinx_theme/assets/styles/sections/_announcement.scss
@@ -1,13 +1,26 @@
+.pst-async-banner-revealer {
+ // Setting height to 0 and overflow to hidden allows us to add up the heights
+ // of this element's children before revealing them.
+ height: 0;
+ overflow: hidden;
+
+ // Height to be set by JavaScript, which should trigger the following
+ // transition rule (unless the user has set their system to reduce motion).
+ transition: height 300ms ease-in-out;
+ @media (prefers-reduced-motion) {
+ transition: none;
+ }
+}
+
.bd-header-version-warning,
.bd-header-announcement {
+ min-height: 3rem;
width: 100%;
display: flex;
position: relative;
align-items: center;
justify-content: center;
text-align: center;
- transition: height 300ms ease-in-out;
- overflow-y: hidden;
padding: 0.5rem 12.5%; // Horizontal padding so the width is 75%
// One breakpoint less than $breakpoint-sidebar-primary. See variables/_layout.scss for more info.
@include media-breakpoint-down(lg) {
@@ -15,20 +28,11 @@
padding: 0.5rem 2%;
}
- &.init {
- position: fixed;
- visibility: hidden;
- }
-
p {
font-weight: bold;
margin: 0;
}
- &:empty {
- display: none;
- }
-
// Ensure there is enough contrast against the background
a {
color: var(--pst-color-inline-code-links);
diff --git a/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po
index cc2090fd1..8926998f2 100644
--- a/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po
+++ b/src/pydata_sphinx_theme/locale/ca/LC_MESSAGES/sphinx.po
@@ -143,7 +143,11 @@ msgstr ""
"theme.readthedocs.io/en/stable/index.html\">Tema PyData Sphinx "
"%(theme_version)s."
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr ""
diff --git a/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po
index 269f014c3..91690218d 100644
--- a/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po
+++ b/src/pydata_sphinx_theme/locale/cs/LC_MESSAGES/sphinx.po
@@ -8,6 +8,7 @@
msgid ""
msgstr ""
+
#: docs/conf.py:94
msgid "Click to expand"
msgstr ""
@@ -142,7 +143,11 @@ msgstr ""
"theme.readthedocs.io/en/stable/index.html\">PyData Sphinx Theme "
"%(theme_version)s."
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr ""
diff --git a/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po
index 65bee9b24..093a8c841 100644
--- a/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po
+++ b/src/pydata_sphinx_theme/locale/en/LC_MESSAGES/sphinx.po
@@ -6,6 +6,7 @@
msgid ""
msgstr ""
+
#: docs/conf.py:94
msgid "Click to expand"
msgstr ""
@@ -135,7 +136,11 @@ msgid ""
"%(theme_version)s."
msgstr ""
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr ""
diff --git a/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po
index 8cc5248bd..46adf1fa6 100644
--- a/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po
+++ b/src/pydata_sphinx_theme/locale/es/LC_MESSAGES/sphinx.po
@@ -9,6 +9,7 @@
msgid ""
msgstr ""
+
#: docs/conf.py:94
msgid "Click to expand"
msgstr ""
@@ -143,7 +144,11 @@ msgstr ""
"theme.readthedocs.io/en/stable/index.html\">Tema PyData Sphinx "
"%(theme_version)s."
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr ""
diff --git a/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po
index 17f5dca6c..9ae92281a 100644
--- a/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po
+++ b/src/pydata_sphinx_theme/locale/fr/LC_MESSAGES/sphinx.po
@@ -10,6 +10,7 @@
msgid ""
msgstr ""
+
#: docs/conf.py:94
msgid "Click to expand"
msgstr "Cliquez pour développer"
@@ -144,7 +145,11 @@ msgstr ""
"theme.readthedocs.io/en/stable/index.html\">Thème PyData Sphinx "
"%(theme_version)s."
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr "Annonce"
diff --git a/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po b/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po
index 65d7cf2c4..de1ba6d09 100644
--- a/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po
+++ b/src/pydata_sphinx_theme/locale/ru/LC_MESSAGES/sphinx.po
@@ -8,6 +8,7 @@
msgid ""
msgstr ""
+
#: docs/conf.py:94
msgid "Click to expand"
msgstr ""
@@ -142,7 +143,11 @@ msgstr ""
"theme.readthedocs.io/en/stable/index.html\\\">PyData Sphinx "
"%(theme_version)s."
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr ""
diff --git a/src/pydata_sphinx_theme/locale/sphinx.pot b/src/pydata_sphinx_theme/locale/sphinx.pot
index 69fbdc69c..11c7f142d 100644
--- a/src/pydata_sphinx_theme/locale/sphinx.pot
+++ b/src/pydata_sphinx_theme/locale/sphinx.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2024-04-29 13:43+0200\n"
+"POT-Creation-Date: 2024-05-10 18:43+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -146,7 +146,11 @@ msgid ""
"%(theme_version)s."
msgstr ""
-#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:1
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:4
+msgid "Version warning"
+msgstr ""
+
+#: src/pydata_sphinx_theme/theme/pydata_sphinx_theme/sections/announcement.html:6
msgid "Announcement"
msgstr ""
diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html
index 9c577da05..9fb914b50 100644
--- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html
+++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html
@@ -68,9 +68,8 @@
{% include "../components/search-field.html" %}
- {%- if theme_announcement -%}
- {% include "sections/announcement.html" %}
- {%- endif %}
+ {% include "sections/announcement.html" %}
+
{% block docs_navbar %}