106 lines
3.7 KiB
HTML
106 lines
3.7 KiB
HTML
{{/*
|
|
Language preference + browser language detection.
|
|
|
|
Rendered inline in <head> on purpose: it must run before the page paints so
|
|
a visitor is never shown a flash of the wrong language, and inlining avoids
|
|
an extra HTTP request for ~1 KB of script.
|
|
|
|
Hugo hands the script everything it needs, so the script never has to guess
|
|
URLs: the home page of every language and the translations of *this* page.
|
|
That keeps it correct even though French is served from the site root ("/")
|
|
while the other languages sit under a prefix ("/en/", "/nl/").
|
|
*/}}
|
|
{{ if hugo.IsMultilingual }}
|
|
{{ $homes := dict }}
|
|
{{ range hugo.Sites }}
|
|
{{ $homes = merge $homes (dict .Language.Lang .Home.RelPermalink) }}
|
|
{{ end }}
|
|
{{ $translations := dict }}
|
|
{{ range .AllTranslations }}
|
|
{{ $translations = merge $translations (dict .Lang .RelPermalink) }}
|
|
{{ end }}
|
|
<script>
|
|
(function () {
|
|
'use strict';
|
|
|
|
var STORAGE_KEY = 'hugo_preferred_language';
|
|
var SESSION_KEY = 'language_redirected';
|
|
|
|
var CURRENT = {{ .Site.Language.Lang }};
|
|
var HOMES = {{ $homes | jsonify | safeJS }};
|
|
var TRANSLATIONS = {{ $translations | jsonify | safeJS }};
|
|
var AVAILABLE = Object.keys(HOMES);
|
|
|
|
function read(store, key) {
|
|
try { return window[store].getItem(key); } catch (e) { return null; }
|
|
}
|
|
|
|
function write(store, key, value) {
|
|
try { window[store].setItem(key, value); } catch (e) { /* private mode */ }
|
|
}
|
|
|
|
/* Match a browser language tag ("nl-BE", "en") against the languages this
|
|
site actually publishes, comparing on the primary subtag. */
|
|
function matchLanguage(tag) {
|
|
var primary = String(tag).toLowerCase().split('-')[0];
|
|
for (var i = 0; i < AVAILABLE.length; i++) {
|
|
if (AVAILABLE[i].toLowerCase().split('-')[0] === primary) {
|
|
return AVAILABLE[i];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function detectFromBrowser() {
|
|
var tags = navigator.languages || (navigator.language ? [navigator.language] : []);
|
|
for (var i = 0; i < tags.length; i++) {
|
|
var match = matchLanguage(tags[i]);
|
|
if (match) { return match; }
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function targetFor(lang) {
|
|
/* Prefer the translation of the page being viewed, so a deep link keeps
|
|
the visitor on the same page in their language. */
|
|
return TRANSLATIONS[lang] || HOMES[lang] || null;
|
|
}
|
|
|
|
function resolveAndRedirect() {
|
|
/* Auto-redirect at most once per browsing session: after that the
|
|
visitor is free to navigate to any language by hand. */
|
|
if (read('sessionStorage', SESSION_KEY)) { return; }
|
|
write('sessionStorage', SESSION_KEY, '1');
|
|
|
|
var stored = read('localStorage', STORAGE_KEY);
|
|
var wanted = (stored && HOMES[stored]) ? stored : detectFromBrowser();
|
|
|
|
if (!wanted || wanted === CURRENT) { return; }
|
|
|
|
var target = targetFor(wanted);
|
|
if (target) {
|
|
window.location.replace(target + window.location.search + window.location.hash);
|
|
}
|
|
}
|
|
|
|
/* Remember an explicit choice made through the language switcher. */
|
|
function rememberChoices() {
|
|
var links = document.querySelectorAll('.language-switch-link');
|
|
for (var i = 0; i < links.length; i++) {
|
|
links[i].addEventListener('click', function () {
|
|
var lang = this.getAttribute('data-lang');
|
|
if (lang) { write('localStorage', STORAGE_KEY, lang); }
|
|
});
|
|
}
|
|
}
|
|
|
|
resolveAndRedirect();
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', rememberChoices);
|
|
} else {
|
|
rememberChoices();
|
|
}
|
|
})();
|
|
</script>
|
|
{{ end }} |