From 77f45b9012cff14ee4531f2d9341aef304f435e4 Mon Sep 17 00:00:00 2001 From: Elijah Greenstein Date: Fri, 29 May 2026 15:28:49 -0700 Subject: [PATCH 1/3] doc: update conf.py and add js for URL migration These changes support migration of the documentation from documentation.ubuntu.com/microcloud to canonical.com/microcloud/docs: - Adds `doc/_static/js/overwrite_links.js` to properly handle links in the flyout menu (version selector). - Updates configuration settings in `doc/conf.py` - Reorganizes JavaScript files into `doc/_static/js` directory, and updates relevant paths Signed-off-by: Elijah Greenstein (cherry picked from commit c155dbd514ee68dd6a88bf7053cf61b09f5dfe19) --- doc/_static/js/overwrite_links.js | 38 +++++++++++++++++++++ doc/_static/{ => js}/rtd-versions-flyout.js | 0 doc/conf.py | 19 ++++++----- 3 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 doc/_static/js/overwrite_links.js rename doc/_static/{ => js}/rtd-versions-flyout.js (100%) diff --git a/doc/_static/js/overwrite_links.js b/doc/_static/js/overwrite_links.js new file mode 100644 index 000000000..c23cdb11a --- /dev/null +++ b/doc/_static/js/overwrite_links.js @@ -0,0 +1,38 @@ + // Replace oldDomain with newDomain + const oldDomain = 'canonical-microcloud-documentation.readthedocs-hosted.com'; + const newDomain = 'canonical.com/microcloud/docs'; + + function escapeRegExp(value) { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + } + + function overwriteMatchingAnchorUrls(container) { + if (!container) return; + + const anchors = container.querySelectorAll('a[href], link[href]'); + const oldDomainRegex = new RegExp(escapeRegExp(oldDomain), 'g'); + + anchors.forEach(anchor => { + anchor.href = anchor.href.replace(oldDomainRegex, newDomain); + }); + } + + overwriteMatchingAnchorUrls(document.querySelector('header')); + + // Use a MutationObserver to wait for the RTD flyout element to appear in the DOM + const observer = new MutationObserver(function(mutations, obs) { + + const rtdFlyout = document.querySelector('readthedocs-flyout'); + if (!rtdFlyout) return; + + obs.disconnect(); + + rtdFlyout.addEventListener('click', function() { + const shadowRoot = rtdFlyout.shadowRoot; + if (!shadowRoot) return; + + overwriteMatchingAnchorUrls(shadowRoot); + }); + }); + + observer.observe(document.body, { childList: true, subtree: true }); diff --git a/doc/_static/rtd-versions-flyout.js b/doc/_static/js/rtd-versions-flyout.js similarity index 100% rename from doc/_static/rtd-versions-flyout.js rename to doc/_static/js/rtd-versions-flyout.js diff --git a/doc/conf.py b/doc/conf.py index 44ed9843e..409bccb4b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -32,14 +32,18 @@ # Copyright string; shown at the bottom of the page copyright = '2014-%s AGPL-3.0, %s' % (datetime.date.today().year, author) -# Use RTD canonical URL to ensure duplicate pages have a single canonical URL -# that includes the version (such as /latest/); helps SEO. -html_baseurl = os.environ.get('READTHEDOCS_CANONICAL_URL', '/') +# Documentation website URL + +version_slug = f'{os.environ.get("READTHEDOCS_VERSION", "local")}' + +slug = 'microcloud/docs' + +html_baseurl = f'https://canonical.com/microcloud/docs/{version_slug}/' # OpenGraph metadata used for social sharing previews ogp_site_url = html_baseurl ogp_site_name = html_title -ogp_image = 'https://documentation.ubuntu.com/microcloud/latest/_static/microcloud_tag.png' +ogp_image = f'https://canonical.com/microcloud/docs/{version_slug}/_static/microcloud_tag.png' html_favicon = '_static/favicon.png' @@ -75,10 +79,6 @@ 'source_edit_link': html_context['github_url'] } -# Project slug -# Required if your project is hosted on documentation.ubuntu.com -slug = 'microcloud' - ####################### # Sitemap configuration: https://sphinx-sitemap.readthedocs.io/ ####################### @@ -205,7 +205,8 @@ html_js_files = [ 'https://assets.ubuntu.com/v1/287a5e8f-bundle.js', - 'rtd-versions-flyout.js', + 'js/rtd-versions-flyout.js', + "js/overwrite_links.js", ] # Feedback button at the top; enabled by default From 76ad6f4c77dc4551606c9aeeb2867903c4ebbff4 Mon Sep 17 00:00:00 2001 From: Elijah Greenstein Date: Thu, 4 Jun 2026 20:51:15 -0700 Subject: [PATCH 2/3] doc/conf.py: temporarily remove "edit page" button This commit removes the "Contribute to this page" button. This change is temporary, and the button will be restored after the docs have moved to canonical.com. Signed-off-by: Elijah Greenstein (cherry picked from commit e599f5a182b22b2f97199596469d35bb952cb779) --- doc/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 409bccb4b..8fa88b06d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -75,9 +75,9 @@ } # Enables the pencil icon to edit pages on GitHub, shown at the top of each page -html_theme_options = { - 'source_edit_link': html_context['github_url'] -} +# html_theme_options = { +# 'source_edit_link': html_context['github_url'] +# } ####################### # Sitemap configuration: https://sphinx-sitemap.readthedocs.io/ From adac6da43c5ac052ed2454fb9dc90545961a362d Mon Sep 17 00:00:00 2001 From: Elijah Greenstein Date: Mon, 6 Jul 2026 15:28:35 -0700 Subject: [PATCH 3/3] doc: consistently overwrite MicroCloud links - Copies the MicroCloud `overwrite_links.js` file into the cloned LXD, MicroCeph, and MicroOVN repos as `overwrite_microcloud_links.js`, so that the JavaScript loads across the integrated docs - Prefixes functions and variables in the MicroCloud `overwrite_links.js` file with `microcloud_` in order to prevent conflicts with the equivalents in the LXD, MicroCeph, and MicroOVN `overwrite_links.js` files. - Reconfigures the Makefile to append `add_config.py` to the end of the MicroOVN `conf.py` so that the addition of `overwrite_microcloud_links.js` to `html_js_files` applies to MicroOVN. Signed-off-by: Elijah Greenstein (cherry picked from commit c19f7958e35a3ed7319e1ca5155554c5dc9b5209) --- doc/.sphinx/_integration/add_config.py | 9 +++++++-- doc/Makefile | 9 ++++++++- doc/_static/js/overwrite_links.js | 20 ++++++++++---------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/doc/.sphinx/_integration/add_config.py b/doc/.sphinx/_integration/add_config.py index 15dc2abb6..696d55674 100644 --- a/doc/.sphinx/_integration/add_config.py +++ b/doc/.sphinx/_integration/add_config.py @@ -12,6 +12,7 @@ if project == "LXD": html_baseurl = "https://canonical.com/lxd/docs/v5.21/" html_css_files = globals().get('html_css_files', []) + ['override-header.css'] + html_js_files = globals().get('html_js_files', []) + ['js/overwrite_microcloud_links.js'] tags.add('integrated') elif project == "MicroCeph": html_baseurl = "https://documentation.ubuntu.com/canonical-microceph/v19.2.0-squid/" @@ -20,9 +21,13 @@ # Override default header styles html_static_path = globals().get('html_static_path', []) + ["_static"] html_css_files = globals().get('html_css_files', []) + ['override-header.css'] + # Add js to overwrite MicroCloud links + html_js_files = globals().get('html_js_files', []) + ['overwrite_microcloud_links.js'] # Add "integrated" to the list of custom tags tags.add('integrated') elif project == "MicroOVN": html_baseurl = "https://ubuntu.com/docs/microovn/24.03/" - custom_tags.append('integrated') - + tags.add('integrated') + html_static_path = globals().get('html_static_path', []) + ["_static"] + # Add js to overwrite MicroCloud links + html_js_files = globals().get('html_js_files', []) + ['overwrite_microcloud_links.js'] diff --git a/doc/Makefile b/doc/Makefile index 317a39b4f..e2ba8b0d0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -109,11 +109,18 @@ integrate: # Add information about where to find the tags/docs to the doc sets cat .sphinx/_integration/add_config.py >> integration/lxd/doc/conf.py cat .sphinx/_integration/add_config.py >> integration/microceph/docs/conf.py - cat .sphinx/_integration/add_config.py >> integration/microovn/docs/custom_conf.py + cat .sphinx/_integration/add_config.py >> integration/microovn/docs/conf.py # Override the MicroOVN tag with the circle of friends one (for consistency) cp .sphinx/_integration/tag.png integration/microovn/docs/.sphinx/_static/microovn.png + # Copy MicroCloud `overwrite_links.js` to all repos + cp _static/js/overwrite_links.js integration/lxd/doc/_static/js/overwrite_microcloud_links.js + mkdir -p integration/microceph/docs/_static + cp _static/js/overwrite_links.js integration/microceph/docs/_static/overwrite_microcloud_links.js + mkdir -p integration/microovn/docs/_static + cp _static/js/overwrite_links.js integration/microovn/docs/_static/overwrite_microcloud_links.js + # `html` builds the integrated docs. html: integrate install mkdir -p $(current_dir)/_build diff --git a/doc/_static/js/overwrite_links.js b/doc/_static/js/overwrite_links.js index c23cdb11a..19a30a5e2 100644 --- a/doc/_static/js/overwrite_links.js +++ b/doc/_static/js/overwrite_links.js @@ -1,26 +1,26 @@ // Replace oldDomain with newDomain - const oldDomain = 'canonical-microcloud-documentation.readthedocs-hosted.com'; - const newDomain = 'canonical.com/microcloud/docs'; + const microcloud_oldDomain = 'canonical-microcloud-documentation.readthedocs-hosted.com'; + const microcloud_newDomain = 'canonical.com/microcloud/docs'; - function escapeRegExp(value) { + function microcloud_escapeRegExp(value) { return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } - function overwriteMatchingAnchorUrls(container) { + function microcloud_overwriteMatchingAnchorUrls(container) { if (!container) return; const anchors = container.querySelectorAll('a[href], link[href]'); - const oldDomainRegex = new RegExp(escapeRegExp(oldDomain), 'g'); + const oldDomainRegex = new RegExp(microcloud_escapeRegExp(microcloud_oldDomain), 'g'); anchors.forEach(anchor => { - anchor.href = anchor.href.replace(oldDomainRegex, newDomain); + anchor.href = anchor.href.replace(oldDomainRegex, microcloud_newDomain); }); } - overwriteMatchingAnchorUrls(document.querySelector('header')); + microcloud_overwriteMatchingAnchorUrls(document.querySelector('header')); // Use a MutationObserver to wait for the RTD flyout element to appear in the DOM - const observer = new MutationObserver(function(mutations, obs) { + const microcloud_observer = new MutationObserver(function(mutations, obs) { const rtdFlyout = document.querySelector('readthedocs-flyout'); if (!rtdFlyout) return; @@ -31,8 +31,8 @@ const shadowRoot = rtdFlyout.shadowRoot; if (!shadowRoot) return; - overwriteMatchingAnchorUrls(shadowRoot); + microcloud_overwriteMatchingAnchorUrls(shadowRoot); }); }); - observer.observe(document.body, { childList: true, subtree: true }); + microcloud_observer.observe(document.body, { childList: true, subtree: true });