[Python-checkins] bpo-31045: Language switch (#2652) (#3023)

Victor Stinner webhook-mailer at python.org
Tue Aug 8 08:13:56 EDT 2017


https://github.com/python/cpython/commit/e93135dbb265e801c0000a19cd9c5428d57d1cf4
commit: e93135dbb265e801c0000a19cd9c5428d57d1cf4
branch: 3.6
author: Julien Palard <julien at palard.fr>
committer: Victor Stinner <victor.stinner at gmail.com>
date: 2017-08-08T14:13:53+02:00
summary:

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 dff9b5f9d62aa0b23f8a255867d09d11890efd1b)

files:
A Doc/tools/static/switchers.js
D Doc/tools/static/version_switch.js
M Doc/Makefile
M Doc/tools/templates/layout.html

diff --git a/Doc/Makefile b/Doc/Makefile
index ae59f3294f1..526269d1e19 100644
--- a/Doc/Makefile
+++ b/Doc/Makefile
@@ -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
diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js
new file mode 100644
index 00000000000..470ff6d33b7
--- /dev/null
+++ b/Doc/tools/static/switchers.js
@@ -0,0 +1,146 @@
+(function() {
+  'use strict';
+
+  // Parses versions in URL segments like:
+  // "3", "dev", "release/2.7" or "3.6rc2"
+  var version_regexs = [
+    '(?:\\d)',
+    '(?:\\d\\.\\d[\\w\\d\\.]*)',
+    '(?:dev)',
+    '(?:release/\\d.\\d[\\x\\d\\.]*)'];
+
+  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 navigate_to_first_existing(urls) {
+    // Navigate to the first existing URL in urls.
+    var url = urls.shift();
+    if (urls.length == 0) {
+      window.location.href = url;
+      return;
+    }
+    $.ajax({
+      url: url,
+      success: function() {
+        window.location.href = url;
+      },
+      error: function() {
+        navigate_to_first_existing(urls);
+      }
+    });
+  }
+
+  function on_version_switch() {
+    var selected_version = $(this).children('option:selected').attr('value') + '/';
+    var url = window.location.href;
+    var current_language = language_segment_from_url(url);
+    var current_version = version_segment_in_url(url);
+    var new_url = url.replace('.org/' + current_language + current_version,
+                              '.org/' + current_language + selected_version);
+    if (new_url != url) {
+      navigate_to_first_existing([
+        new_url,
+        url.replace('.org/' + current_language + current_version,
+                    '.org/' + selected_version),
+        'https://docs.python.org/' + current_language + selected_version,
+        'https://docs.python.org/' + selected_version,
+        'https://docs.python.org/'
+      ]);
+    }
+  }
+
+  function on_language_switch() {
+    var selected_language = $(this).children('option:selected').attr('value') + '/';
+    var url = window.location.href;
+    var current_language = language_segment_from_url(url);
+    var current_version = version_segment_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) {
+      navigate_to_first_existing([
+        new_url,
+        'https://docs.python.org/'
+      ]);
+    }
+  }
+
+  // Returns the path segment of the language as a string, like 'fr/'
+  // or '' if not found.
+  function language_segment_from_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 of the version as a string, like '3.6/'
+  // or '' if not found.
+  function version_segment_in_url(url) {
+    var language_segment = '(?:(?:' + Object.keys(all_languages).join('|') + ')/)';
+    var version_segment = '(?:(?:' + version_regexs.join('|') + ')/)';
+    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 language_segment = language_segment_from_url(window.location.href);
+    var current_language = language_segment.replace(/\/+$/g, '') || 'en';
+    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);
+  });
+})();
diff --git a/Doc/tools/static/version_switch.js b/Doc/tools/static/version_switch.js
deleted file mode 100644
index 8b36a616718..00000000000
--- a/Doc/tools/static/version_switch.js
+++ /dev/null
@@ -1,67 +0,0 @@
-(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',
-  };
-
-  function build_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 patch_url(url, new_version) {
-    var url_re = /\.org\/(\d|py3k|dev|((release\/)?\d\.\d[\w\d\.]*))\//,
-        new_url = url.replace(url_re, '.org/' + new_version + '/');
-
-    if (new_url == url && !new_url.match(url_re)) {
-      // python 2 url without version?
-      new_url = url.replace(/\.org\//, '.org/' + new_version + '/');
-    }
-    return new_url;
-  }
-
-  function on_switch() {
-    var selected = $(this).children('option:selected').attr('value');
-
-    var url = window.location.href,
-        new_url = patch_url(url, selected);
-
-    if (new_url != url) {
-      // check beforehand if url exists, else redirect to version's start page
-      $.ajax({
-        url: new_url,
-        success: function() {
-           window.location.href = new_url;
-        },
-        error: function() {
-           window.location.href = 'https://docs.python.org/' + selected;
-        }
-      });
-    }
-  }
-
-  $(document).ready(function() {
-    var release = DOCUMENTATION_OPTIONS.VERSION;
-    var version = release.substr(0, 3);
-    var select = build_select(version, release);
-
-    $('.version_switcher_placeholder').html(select);
-    $('.version_switcher_placeholder select').bind('change', on_switch);
-  });
-})();
diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html
index 640d8b30493..c2106678ac6 100644
--- a/Doc/tools/templates/layout.html
+++ b/Doc/tools/templates/layout.html
@@ -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 %}
@@ -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() {



More information about the Python-checkins mailing list