Skip to content

Commit

Permalink
feature: add the switcher to change versions and locales
Browse files Browse the repository at this point in the history
  • Loading branch information
cheekyshibe committed Mar 15, 2021
1 parent b5351c5 commit d3b5f1b
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pydata_sphinx_theme/docs-navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,11 @@
{%- block icon_links -%}
{%- include "icon-links.html" with context -%}
{%- endblock %}

<ul class="navbar-nav">
<li class="version_switcher nav-item dropdown">
{%- include "version-switcher.html" %}
</li>
</ul>
</div>
</div>
5 changes: 5 additions & 0 deletions pydata_sphinx_theme/theme.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ search_bar_position = sidebar
navigation_with_keys = True
show_toc_level = 1
navbar_align = content
use_version_switch = True
version_switch_json_url = /versions.json
version_switch_enable_locale = True
version_switch_locales = zh, en

145 changes: 145 additions & 0 deletions pydata_sphinx_theme/version-switcher.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{% if theme_use_version_switch == true %}
<script type="text/javascript">
(function () {
const version_json_url = "{{theme_version_switch_json_url}}";
const enable_locale = "{{theme_version_switch_enable_locale}}" === 'True';

// TODO check how to pass an array instead of raw string
const all_locales = "{{theme_version_switch_locales}}";

// Remote version should like this.
// .name and .alias must be unique in each locale.
// It's not necessary to have same versions in all locales.
// When locale is enabled, there must be only one .default=true item in each locale to indicate which one should be redirect if target version doesn't exist in target locale.

/*
let all_versions = {
"en": [
{
"name": "V1.2.0",
"url": "v1.2.0",
"alias": ["latest"],
"default": true
},
{
"name": "v1.1.0",
"url": "v1.1.0",
"alias": []
},
],
"zh":[
{
"name": "v1.0.0",
"url": "v1.0.0",
"alias": []
"default": true
},
],
};
*/

function parse_current_url() {
// sphinx will fill here.
let page_name = "{{pagename}}.html";

if (location.pathname.slice(-page_name.length) !== page_name) {
// Sphinx generated pages should have exactly same suffix
throw 'page suffix do not match requirements';
}
// Get base URL by Removing '/' and page_name
let base_url = location.pathname.slice(0, -(page_name.length + 1));
let parts = base_url.split('/');

let current_version = parts.pop();
let current_locale = '';

if (enable_locale) {
if (parts.length < 1) {
throw 'page base URL do not have any locale information';
}
current_locale = parts.pop();
}
// This is base URL without any version or locate.
let global_base_url = parts.join('/')

return {page_name, base_url, current_version, current_locale, global_base_url};
}

function validate(all_versions, info) {
// TODO check all_versions is valid

// TODO check current_locale and current_version is valid
return;
}

// Set locale or version to null to indicate unchanged property.
function construct_url(info, target_locale, target_version) {
let segments = [info.global_base_url];

if (target_locale == null) {
target_locale = info.current_locale;
}
if (target_version == null) {
target_version = info.current_version;
}
if (enable_locale) {
segments.push(target_locale);
}
segments.push(target_version);
segments.push(info.page_name);
return segments.join('/') + location.hash;
}

function render(all_versions, info) {
function on_switch(evt) {
evt.preventDefault()
let selected = evt.currentTarget.getAttribute('key');

// TODO process with alias problem, e.g. do not jump if target is just an alias of current one.
let new_url = construct_url(info, null, selected);
window.location.assign(new_url);
}
// fill the current version in the dropdown
document.getElementById("version-dropdown").innerText = 'latest';

// TODO show alias as well
const getVersionLink = () => {
return all_versions[info.current_locale].map((item) => {
return item.name;
}).map(key => `<button class="dropdown-item" key="${key}">${key}<\/button>`)
}
// fill the version menu
document.getElementById("version-menu").innerHTML = getVersionLink().join('');

// bind the changes to this menu to trigger the switching function
$('#version-menu button').on('click', on_switch)

// TODO add locale button
}


// Trigger fetch as earlier as possible to speedup page loading.
let p = fetch(version_json_url).then((resp) => {
return resp.json()
});

$(document).ready(function () {
let info = parse_current_url();

p.then((all_versions) => {
validate(all_versions, info);
render(all_versions, info);
})
});
})();

</script>

<button id="version-dropdown" class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<!-- placeholder for javascript filling above -->
</button>
<div id="version-menu" class="dropdown-menu" style="min-width: 6rem;">
<!-- placeholder for javascript filling above -->
</div>

{% endif %}

0 comments on commit d3b5f1b

Please sign in to comment.