Skip to content

Commit e93135d

Browse files
JulienPalardvstinner
authored andcommitted
bpo-31045: Language switch (#2652) (#3023)
* Doc: Indicate the language * Renaming version_switcher to switchers (to add language_switcher). * Adding language switch. * Doc switchers: Enhance readability of regex parsing versions. * Doc switchers: Desambiguate the need of a replace(/\/+$/g, '') by proper naming. * Doc switchers: py3k can't reach js, it's redirected server-side by nginx. * Doc switchers: Examples matching actual regexes. * Doc switchers: Better fallback on unexisting translated version. (cherry picked from commit dff9b5f)
1 parent 9d7d928 commit e93135d

File tree

4 files changed

+151
-71
lines changed

4 files changed

+151
-71
lines changed

Doc/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,12 @@ serve:
167167

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

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

177177
# for stable releases: only build if not in pre-release stage (alpha, beta)
178178
# release candidate downloads are okay, since the stable tree can be in that stage

Doc/tools/static/switchers.js

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
(function() {
2+
'use strict';
3+
4+
// Parses versions in URL segments like:
5+
// "3", "dev", "release/2.7" or "3.6rc2"
6+
var version_regexs = [
7+
'(?:\\d)',
8+
'(?:\\d\\.\\d[\\w\\d\\.]*)',
9+
'(?:dev)',
10+
'(?:release/\\d.\\d[\\x\\d\\.]*)'];
11+
12+
var all_versions = {
13+
'3.7': 'dev (3.7)',
14+
'3.6': '3.6',
15+
'3.5': '3.5',
16+
'3.4': '3.4',
17+
'3.3': '3.3',
18+
'2.7': '2.7',
19+
};
20+
21+
var all_languages = {
22+
'en': 'English',
23+
'fr': 'Français',
24+
};
25+
26+
function build_version_select(current_version, current_release) {
27+
var buf = ['<select>'];
28+
29+
$.each(all_versions, function(version, title) {
30+
buf.push('<option value="' + version + '"');
31+
if (version == current_version)
32+
buf.push(' selected="selected">' + current_release + '</option>');
33+
else
34+
buf.push('>' + title + '</option>');
35+
});
36+
37+
buf.push('</select>');
38+
return buf.join('');
39+
}
40+
41+
function build_language_select(current_language) {
42+
var buf = ['<select>'];
43+
44+
$.each(all_languages, function(language, title) {
45+
if (language == current_language)
46+
buf.push('<option value="' + language + '" selected="selected">' +
47+
all_languages[current_language] + '</option>');
48+
else
49+
buf.push('<option value="' + language + '">' + title + '</option>');
50+
});
51+
buf.push('</select>');
52+
return buf.join('');
53+
}
54+
55+
function navigate_to_first_existing(urls) {
56+
// Navigate to the first existing URL in urls.
57+
var url = urls.shift();
58+
if (urls.length == 0) {
59+
window.location.href = url;
60+
return;
61+
}
62+
$.ajax({
63+
url: url,
64+
success: function() {
65+
window.location.href = url;
66+
},
67+
error: function() {
68+
navigate_to_first_existing(urls);
69+
}
70+
});
71+
}
72+
73+
function on_version_switch() {
74+
var selected_version = $(this).children('option:selected').attr('value') + '/';
75+
var url = window.location.href;
76+
var current_language = language_segment_from_url(url);
77+
var current_version = version_segment_in_url(url);
78+
var new_url = url.replace('.org/' + current_language + current_version,
79+
'.org/' + current_language + selected_version);
80+
if (new_url != url) {
81+
navigate_to_first_existing([
82+
new_url,
83+
url.replace('.org/' + current_language + current_version,
84+
'.org/' + selected_version),
85+
'https://docs.python.org/' + current_language + selected_version,
86+
'https://docs.python.org/' + selected_version,
87+
'https://docs.python.org/'
88+
]);
89+
}
90+
}
91+
92+
function on_language_switch() {
93+
var selected_language = $(this).children('option:selected').attr('value') + '/';
94+
var url = window.location.href;
95+
var current_language = language_segment_from_url(url);
96+
var current_version = version_segment_in_url(url);
97+
if (selected_language == 'en/') // Special 'default' case for english.
98+
selected_language = '';
99+
var new_url = url.replace('.org/' + current_language + current_version,
100+
'.org/' + selected_language + current_version);
101+
if (new_url != url) {
102+
navigate_to_first_existing([
103+
new_url,
104+
'https://docs.python.org/'
105+
]);
106+
}
107+
}
108+
109+
// Returns the path segment of the language as a string, like 'fr/'
110+
// or '' if not found.
111+
function language_segment_from_url(url) {
112+
var language_regexp = '\.org/(' + Object.keys(all_languages).join('|') + '/)';
113+
var match = url.match(language_regexp);
114+
if (match !== null)
115+
return match[1];
116+
return '';
117+
}
118+
119+
// Returns the path segment of the version as a string, like '3.6/'
120+
// or '' if not found.
121+
function version_segment_in_url(url) {
122+
var language_segment = '(?:(?:' + Object.keys(all_languages).join('|') + ')/)';
123+
var version_segment = '(?:(?:' + version_regexs.join('|') + ')/)';
124+
var version_regexp = '\\.org/' + language_segment + '?(' + version_segment + ')';
125+
var match = url.match(version_regexp);
126+
if (match !== null)
127+
return match[1];
128+
return ''
129+
}
130+
131+
$(document).ready(function() {
132+
var release = DOCUMENTATION_OPTIONS.VERSION;
133+
var language_segment = language_segment_from_url(window.location.href);
134+
var current_language = language_segment.replace(/\/+$/g, '') || 'en';
135+
var version = release.substr(0, 3);
136+
var version_select = build_version_select(version, release);
137+
138+
$('.version_switcher_placeholder').html(version_select);
139+
$('.version_switcher_placeholder select').bind('change', on_version_switch);
140+
141+
var language_select = build_language_select(current_language);
142+
143+
$('.language_switcher_placeholder').html(language_select);
144+
$('.language_switcher_placeholder select').bind('change', on_language_switch);
145+
});
146+
})();

Doc/tools/static/version_switch.js

Lines changed: 0 additions & 67 deletions
This file was deleted.

Doc/tools/templates/layout.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
style="vertical-align: middle; margin-top: -1px"/></li>
55
<li><a href="https://www.python.org/">Python</a>{{ reldelim1 }}</li>
66
<li>
7-
{%- if versionswitcher is defined %}
7+
{%- if switchers is defined %}
8+
<span class="language_switcher_placeholder">{{ language or 'en' }}</span>
89
<span class="version_switcher_placeholder">{{ release }}</span>
910
<a href="{{ pathto('index') }}">{% trans %}Documentation {% endtrans %}</a>{{ reldelim1 }}
1011
{%- else %}
@@ -41,7 +42,7 @@
4142
<link rel="canonical" href="https://docs.python.org/3/{{pagename}}.html" />
4243
{% if builder != "htmlhelp" %}
4344
{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
44-
{% if versionswitcher is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/version_switch.js', 1) }}"></script>{% endif %}
45+
{% if switchers is defined and not embedded %}<script type="text/javascript" src="{{ pathto('_static/switchers.js', 1) }}"></script>{% endif %}
4546
{% if pagename == 'whatsnew/changelog' and not embedded %}
4647
<script type="text/javascript">
4748
$(document).ready(function() {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy