Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,12 @@ serve:

# for development releases: always build
autobuild-dev:
make dist SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1 -A versionswitcher=1'
make dist SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1 -A switchers=1'
-make suspicious

# for quick rebuilds (HTML only)
autobuild-dev-html:
make html SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1 -A versionswitcher=1'
make html SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1 -A switchers=1'

# for stable releases: only build if not in pre-release stage (alpha, beta)
# release candidate downloads are okay, since the stable tree can be in that stage
Expand Down
123 changes: 123 additions & 0 deletions Doc/tools/static/switchers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
(function() {
'use strict';

var all_versions = {
'3.7': 'dev (3.7)',
'3.6': '3.6',
'3.5': '3.5',
'3.4': '3.4',
'3.3': '3.3',
'2.7': '2.7',
};

var all_languages = {
'en': 'English',
'fr': 'Français',
};

function build_version_select(current_version, current_release) {
var buf = ['<select>'];

$.each(all_versions, function(version, title) {
buf.push('<option value="' + version + '"');
if (version == current_version)
buf.push(' selected="selected">' + current_release + '</option>');
else
buf.push('>' + title + '</option>');
});

buf.push('</select>');
return buf.join('');
}

function build_language_select(current_language) {
var buf = ['<select>'];

$.each(all_languages, function(language, title) {
if (language == current_language)
buf.push('<option value="' + language + '" selected="selected">' +
all_languages[current_language] + '</option>');
else
buf.push('<option value="' + language + '">' + title + '</option>');
});
buf.push('</select>');
return buf.join('');
}

function naviagate_if_exists(url, default_url) {
// check beforehand if url exists, else redirect to default_url.
$.ajax({
url: url,
success: function() {
window.location.href = url;
},
error: function() {
window.location.href = default_url;
}
});
}

function on_version_switch() {
var selected_version = $(this).children('option:selected').attr('value') + '/';
var url = window.location.href;
var current_language = find_language_in_url(url);
var current_version = find_version_in_url(url);
var new_url = url.replace('.org/' + current_language + current_version,
'.org/' + current_language + selected_version);
if (new_url != url) {
naviagate_if_exists(new_url, 'https://docs.python.org/' +

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you put docs.python.org in a global constant? It may be useful to have a different value for the doc rendered for readthedocs.org, no? In this case, the ".org/" hack doesn't work anymore :-) Readthedocs.org uses readthedocs.io (not .org) for user docs.

current_language + selected_version);
}
}

function on_language_switch() {
var selected_language = $(this).children('option:selected').attr('value') + '/';
var url = window.location.href;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most of the code is copied from on_version_switch(), can't you try to factorize the code a little bit more?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I could factorize it, I actually though about it a few seconds, but I don't see how it can make code any better, in the "more readable" sense. Yes it can probably be made shorter (not even sure). But I like the readability of:

var new_url = url.replace('.org/' + current_language + current_version,
                          '.org/' + selected_language + current_version);

and

var new_url = url.replace('.org/' + current_language + current_version,
                          '.org/' + current_language + selected_version);

and factorizing it will put a new level of "indirection", making it ultimately harder to read.

var current_language = find_language_in_url(url);
var current_version = find_version_in_url(url);
if (selected_language == 'en/') // Special 'default' case for english.
selected_language = '';
var new_url = url.replace('.org/' + current_language + current_version,
'.org/' + selected_language + current_version);
if (new_url != url) {
naviagate_if_exists(new_url, 'https://docs.python.org/' +
selected_language + current_version);
}
}

// Returns the path segment as a string, like 'fr/' or '' if not found.
function find_language_in_url(url) {
var language_regexp = '\.org/(' + Object.keys(all_languages).join('|') + '/)';
var match = url.match(language_regexp);
if (match !== null)
return match[1];
return '';
}

// Returns the path segment as a string, like '3.6/' or '' if not found.
function find_version_in_url(url) {
var language_segment = '(?:(?:' + Object.keys(all_languages).join('|') + ')/)';
var version_segment = '(?:(?:\\d|py3k|dev|(?:(?:release/)?\\d\\.\\d[\\w\\d\\.]*))/)';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to not hardcode versions here neither. Please put py3k, dev, etc. in a global constant array at the top. By the way, I don't think that "py3k" is still needed.

You can please document in a comment which kinds of versions are accepted here? Example:

// Version examples: "/3", "/dev", "/release/2.7" or "/3.6rc2"

I'm not sure about "/3.6rc2": I wanted to test https://docs.python.org/3.6rc2/ but the HTTP server is sick and fails with HTTP 503 Service Unavailable :-(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed an enhancement about the readability of the regex, but I'll have to try later the existance/unexistance of urls like /py3k/ and so on. According to a google search https://docs.python.org/dev/py3k may even exist.

var version_regexp = '\\.org/' + language_segment + '?(' + version_segment + ')';
var match = url.match(version_regexp);
if (match !== null)
return match[1];
return ''
}

$(document).ready(function() {
var release = DOCUMENTATION_OPTIONS.VERSION;
var current_language = find_language_in_url(window.location.href).replace(
/\/+$/g, '') || 'en';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the .replace() here. What does it do? Why is it needed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disambiguated it by renaming functions and creating an intermediate named variable.

find_language_in_url, now called language_segment_from_url extract a path segment like 3.6/, not a language tag, so we have to strip the / to get the language tag.

This is usefull to disambiguate between having no language in URL being the empty string versus having a language in the URL being "LANGUAGE_TAG/", so we can later concatenate "language + version" and it gives the expected result:

  • '' + "3.5/" → "3.5/"
  • "fr/" + "" → "fr/"
  • "fr/" + "3.5/" → "fr/3.5/"

this permit to easily find and replace an optional language and an optional version in an URL like:

var new_url = url.replace('.org/' + current_language + current_version,
                          '.org/' + selected_language + current_version);

var version = release.substr(0, 3);
var version_select = build_version_select(version, release);

$('.version_switcher_placeholder').html(version_select);
$('.version_switcher_placeholder select').bind('change', on_version_switch);

var language_select = build_language_select(current_language);

$('.language_switcher_placeholder').html(language_select);
$('.language_switcher_placeholder select').bind('change', on_language_switch);
});
})();
67 changes: 0 additions & 67 deletions Doc/tools/static/version_switch.js

This file was deleted.

5 changes: 3 additions & 2 deletions Doc/tools/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a>{{ reldelim1 }}</li>
<li>
{%- if versionswitcher is defined %}
{%- if switchers is defined %}
<span class="language_switcher_placeholder">{{ language or 'en' }}</span>
<span class="version_switcher_placeholder">{{ release }}</span>
<a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }}
{%- else %}
Expand Down Expand Up @@ -41,7 +42,7 @@
<link rel="canonical" href="https://docs.python.org/3/{{pagename}}.html" />
{% if builder != "htmlhelp" %}
{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
{% if versionswitcher is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/version_switch.js', 1) }}"></script>{% endif %}
{% if switchers is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %}
{% if pagename == 'whatsnew/changelog' and not embedded %}
<script type="text/javascript">
$(document).ready(function() {
Expand Down