diff --git a/assets/js/versions.js b/assets/js/versions.js new file mode 100644 index 00000000..5e39342b --- /dev/null +++ b/assets/js/versions.js @@ -0,0 +1,78 @@ +/* +Copyright 2025 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function appendVersion(parent, name, url) { + // The list item + const li = document.createElement("li"); + parent.appendChild(li); + + // The link + const a = document.createElement("a"); + a.classList.add("dropdown-item") + a.setAttribute("href", url); + li.appendChild(a); + + // Handle clicks manually to preserve the current path / fragment + a.addEventListener("click", (ev) => { + // If the URL is a relative link (i.e. the historical versions changelog), just + // let the browser load it + if (url.startsWith("/")) { + return; + } + + // Stop further event handling + ev.preventDefault(); + ev.stopPropagation(); + + // Try to find the current version segment + const href = window.location.href; + const matches = href.match(/\/unstable\/|\/latest\/|\/v\d+.\d+\//g); + if (!matches) { + window.location.href = url; + return; + } + + // Replace the segment + window.location.href = href.replace(matches[0], `/${name}/`); + }); + + // The link text + const text = document.createTextNode(name); + a.appendChild(text); +} + +// TODO: Load /latest/versions.json +fetch("/versions.json") + .then(r => r.json()) + .then(versions => { + // Find the surrounding list element + const ul = document.querySelector("ul#version-selector"); + if (!ul) { + console.error("Cannot populate version selector: ul element not found"); + return; + } + + // Add an entry for the unstable version + appendVersion(ul, "unstable", "https://spec.matrix.org/unstable"); + + // Add an entry for each proper version + for (const version of versions) { + appendVersion(ul, version.name, `https://spec.matrix.org/${version.name}`); + } + + // For historical versions, simply link to the changelog + appendVersion(ul, "historical", "/changelog/historical/"); + }); diff --git a/changelogs/internal/newsfragments/2256.clarification b/changelogs/internal/newsfragments/2256.clarification new file mode 100644 index 00000000..468f55d5 --- /dev/null +++ b/changelogs/internal/newsfragments/2256.clarification @@ -0,0 +1 @@ +Add version picker in the navbar. diff --git a/config/_default/hugo.toml b/config/_default/hugo.toml index 4b817cd0..b09b9562 100644 --- a/config/_default/hugo.toml +++ b/config/_default/hugo.toml @@ -78,6 +78,10 @@ current_version_url = "https://spec.matrix.org/latest" # major = "1" # minor = "16" +[[params.versions]] +# We must include this parameter to enable docsy's version picker in the navbar. The picker +# is populated automatically in navbar-version-selector.html. + # User interface configuration [params.ui] # Collapse HTTP API and event
elements diff --git a/layouts/_partials/hooks/body-end.html b/layouts/_partials/hooks/body-end.html index 75997417..c1324c0a 100644 --- a/layouts/_partials/hooks/body-end.html +++ b/layouts/_partials/hooks/body-end.html @@ -8,3 +8,5 @@ */}} {{ $toc := resources.Get "js/toc.js" -}} +{{ $versions := resources.Get "js/versions.js" -}} + diff --git a/layouts/_partials/navbar-version-selector.html b/layouts/_partials/navbar-version-selector.html new file mode 100644 index 00000000..215bca62 --- /dev/null +++ b/layouts/_partials/navbar-version-selector.html @@ -0,0 +1,18 @@ +{{- /* + + A version of the navbar-version-selector.html partial in Docsy, + modified to read the versions from /versions.json. + +*/ -}} + +{{ $changelog := site.GetPage "changelog" }} +{{ $pages := $changelog.RegularPages.ByDate.Reverse }} + + diff --git a/layouts/docs/baseof.html b/layouts/docs/baseof.html index 4f353ce2..b5b7a0f0 100644 --- a/layouts/docs/baseof.html +++ b/layouts/docs/baseof.html @@ -5,6 +5,25 @@ */}} +{{/* Generate a static file versions.json that can be used to populate the version picker */}} +{{ if .IsHome }} + {{- /* Load all changelog subpages, sorted by release date */ -}} + {{ $changelog := site.GetPage "changelog" }} + {{ $pages := $changelog.RegularPages.ByDate.Reverse }} + + {{- /* Collect proper versions and build metadata dicts */ -}} + {{ $versions := slice }} + {{ range $pages }} + {{ if findRE `^v[0-9]+\.[0-9]+$` .Params.linkTitle }} + {{ $versions = $versions | append (dict "name" .Params.linkTitle "date" .Params.date ) }} + {{ end }} + {{ end }} + + {{- /* Generate the JSON */ -}} + {{ $json := jsonify $versions }} + {{ $noop := (resources.FromString "/versions.json" $json).Permalink }} +{{ end }} +