Skip to content

Commit 4291460

Browse files
authored
docs: add version switcher to docs page (#10135)
1 parent 91f2cb0 commit 4291460

2 files changed

Lines changed: 121 additions & 1 deletion

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Version switcher for the user guide sidebar.
3+
*
4+
* Injects the sphinx_rtd_theme's native ".switch-menus > .version-switch"
5+
* scaffolding above the search box in the left sidebar, containing a <select>
6+
* so readers can jump between:
7+
* - stable: https://codeigniter.com/user_guide/
8+
* - latest (in-progress): https://codeigniter4.github.io/userguide/
9+
* - local build: file:// or localhost, etc. (only shown when not on a deployed host)
10+
*/
11+
(() => {
12+
const VERSIONS = [
13+
{
14+
slug: 'stable',
15+
label: 'Stable',
16+
host: 'codeigniter.com',
17+
pathPrefix: '/user_guide/',
18+
},
19+
{
20+
slug: 'latest (in-progress)',
21+
label: 'Latest (in-progress)',
22+
host: 'codeigniter4.github.io',
23+
pathPrefix: '/userguide/',
24+
},
25+
];
26+
27+
const LOCAL = Object.freeze({
28+
slug: 'local build',
29+
label: 'Local build',
30+
host: null,
31+
pathPrefix: null,
32+
});
33+
34+
const detect_current = () =>
35+
VERSIONS.find((version) => version.host === window.location.hostname) ?? LOCAL;
36+
37+
/*
38+
* Derive the absolute URL of the documentation root by inspecting the
39+
* <script> tag Sphinx always injects for documentation_options.js. Its
40+
* resolved .src is absolute, so we can back out the directory that
41+
* contains _static/, which is the doc root. This works identically for
42+
* http(s), file://, and localhost.
43+
*/
44+
const doc_root_url = () => {
45+
const opts = document.querySelector('script[src*="documentation_options.js"]');
46+
47+
if (!opts) {
48+
return null;
49+
}
50+
51+
const idx = opts.src.lastIndexOf('/_static/');
52+
53+
return idx < 0 ? null : opts.src.slice(0, idx + 1);
54+
};
55+
56+
const current_page_path = () => {
57+
const root = doc_root_url();
58+
59+
if (!root) {
60+
return '';
61+
}
62+
63+
const here = window.location.href.split('#')[0].split('?')[0];
64+
65+
return here.startsWith(root) ? here.slice(root.length) : '';
66+
};
67+
68+
const url_for = ({ host, pathPrefix }) =>
69+
`https://${host}${pathPrefix}${current_page_path()}${window.location.hash}`;
70+
71+
const build = () => {
72+
const searchArea = document.querySelector('.wy-side-nav-search');
73+
const searchForm = searchArea?.querySelector('[role="search"]');
74+
75+
if (!searchArea || !searchForm) {
76+
return;
77+
}
78+
79+
if (searchArea.querySelector('.switch-menus')) {
80+
return;
81+
}
82+
83+
const current = detect_current();
84+
const entries = current === LOCAL ? [LOCAL, ...VERSIONS] : VERSIONS;
85+
86+
const select = document.createElement('select');
87+
select.setAttribute('aria-label', 'Select documentation version');
88+
89+
for (const entry of entries) {
90+
const option = document.createElement('option');
91+
option.value = entry.host ? url_for(entry) : '';
92+
option.textContent = entry.label;
93+
option.selected = entry.slug === current.slug;
94+
select.append(option);
95+
}
96+
97+
select.addEventListener('change', () => {
98+
if (select.value) {
99+
window.location.href = select.value;
100+
}
101+
});
102+
103+
const versionSwitch = document.createElement('div');
104+
versionSwitch.className = 'version-switch';
105+
versionSwitch.append(select);
106+
107+
const switchMenus = document.createElement('div');
108+
switchMenus.className = 'switch-menus';
109+
switchMenus.append(versionSwitch);
110+
111+
searchArea.insertBefore(switchMenus, searchForm);
112+
};
113+
114+
if (document.readyState === 'loading') {
115+
document.addEventListener('DOMContentLoaded', build, { once: true });
116+
} else {
117+
build();
118+
}
119+
})();

user_guide_src/source/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@
111111
# A list of JS files.
112112
html_js_files = [
113113
'js/citheme.js',
114-
'js/carbon.js'
114+
'js/carbon.js',
115+
'js/version_switcher.js'
115116
]
116117

117118
# -- Options for LaTeX output --------------------------------------------------

0 commit comments

Comments
 (0)