diff --git a/assets/_relearn_versionindex.js b/assets/_relearn_versionindex.js
new file mode 100644
index 0000000000..31c7fdcf61
--- /dev/null
+++ b/assets/_relearn_versionindex.js
@@ -0,0 +1,2 @@
+{{- $versions := partialCached "_relearn/siteVersions.gotmpl" . -}}
+var relearn_versionindex = {{ $versions | jsonify (dict "indent" " ") }}
diff --git a/assets/js/theme.js b/assets/js/theme.js
index dcd1ab92c9..b94f0b1d6f 100644
--- a/assets/js/theme.js
+++ b/assets/js/theme.js
@@ -1950,3 +1950,81 @@ function normalizeColor(c) {
c = c.replace(/ +/g, ' ');
return c;
}
+
+function initVersionIndex(index) {
+ if (!index || !index.length) {
+ return;
+ }
+
+ var select = document.querySelector('#R-select-version');
+ if (!select) {
+ return;
+ }
+
+ // Remember the currently selected option
+ var selectedOption = null;
+ if (select.selectedIndex >= 0) {
+ selectedOption = select.options[select.selectedIndex].cloneNode(true);
+ }
+
+ // Remove all existing options
+ while (select.firstChild) {
+ select.removeChild(select.firstChild);
+ }
+
+ // Add all options from the index
+ index.forEach(function (version) {
+ // Create new option element
+ var option = document.createElement('option');
+ option.id = 'R-select-version-' + version.value;
+ option.value = version.value;
+ option.dataset.abs = version.isAbs;
+ option.dataset.uri = version.baseURL;
+ option.dataset.identifier = version.identifier;
+ option.textContent = version.title;
+
+ // Add the option to the select
+ select.appendChild(option);
+ });
+
+ // Re-select the previously selected option if it exists
+ if (selectedOption) {
+ for (var i = 0; i < select.options.length; i++) {
+ if (select.options[i].dataset.identifier === selectedOption.dataset.identifier) {
+ select.selectedIndex = i;
+ return;
+ }
+ }
+
+ // If the previously selected option doesn't exist, add it at the end
+ select.appendChild(selectedOption);
+ select.selectedIndex = select.options.length - 1;
+ return;
+ } else if (select.options.length > 0) {
+ // If there was no selection before, select the first option
+ select.selectedIndex = 0;
+ return;
+ }
+}
+
+function initVersionJs() {
+ if (window.relearn.version_js_url) {
+ var js = document.createElement('script');
+ // we need to add a random number on each call to read this file fresh from the server;
+ // it may reside in a different Hugo instance and therefore we do not know when it changes
+ var url = new URL(window.relearn.version_js_url, window.location.href);
+ var randomNum = Math.floor(Math.random() * 1000000);
+ url.searchParams.set('v', randomNum.toString());
+ js.src = url.toString();
+ js.setAttribute('async', '');
+ js.onload = function () {
+ initVersionIndex(relearn_versionindex);
+ };
+ js.onerror = function (e) {
+ console.error('Error getting version index file');
+ };
+ document.head.appendChild(js);
+ }
+}
+
+initVersionJs();
diff --git a/docs/config/_default/params.toml b/docs/config/_default/params.toml
index 4a9ee5f5d5..f0a866a046 100644
--- a/docs/config/_default/params.toml
+++ b/docs/config/_default/params.toml
@@ -134,6 +134,40 @@ errorignore = []
# See the docs how this works.
# [relearn.dependencies]
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# Versioning
+# These options control versioning of your site..
+
+# Available verions
+# Default: not set
+# A list of version items that are available to the version switcher. Each item
+# can contain the following parameter:
+# - identifier: mandatory, not displayed
+# - title: mandatory, text, shown in the version swicher
+# - baseURL: mandatory, the base URL of that specific version
+# - isLateste: optional, but must be set exactly once in the set of items, marks
+# the latest version of the site, used to retrieve the index of available versions
+# during runtime for older sites.
+versions = ''
+
+# Version identifier of this site
+# Default: not set
+# If versioning is configured, this is mandatory and must be one of the identifiers
+# from the `versions` array.
+version = 'v1.0'
+
+# Hide deprecated version warning
+# Default: false
+# If you want to hide the deprecation warning, visible on all pages that to not
+# belong to the latest version of the site, set this to `true`.
+disableVersionWarning = false
+
+# URL of the version index file relative to the language home.
+# Default: 'versionindex.js'
+# You have to set this option if your page already has a content file named
+# `versionindex.js` in the language home.
+versionIndexURL = 'versionindex.js'
+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Topbar
# These options modify the topbar appearance.
@@ -318,6 +352,7 @@ disableShortcutsTitle = false
# all accept the `icon` parameter to overwrite the default icon
# - languageswitcher: will display the language switcher
# - variantswitcher: will display the variant switcher
+# - versionswitcher: will display the version switcher
# - historyclearer: will display a button to clear the history of visited links
# The sidebar header menu.
diff --git a/docs/content/authoring/frontmatter/reference/frontmatter.toml b/docs/content/authoring/frontmatter/reference/frontmatter.toml
index 9fa643b08d..944ef32619 100644
--- a/docs/content/authoring/frontmatter/reference/frontmatter.toml
+++ b/docs/content/authoring/frontmatter/reference/frontmatter.toml
@@ -190,6 +190,7 @@ collapsibleMenu = true
# all accept the `icon` parameter to overwrite the default icon
# - languageswitcher: will display the language switcher
# - variantswitcher: will display the variant switcher
+# - versionswitcher: will display the version switcher
# - historyclearer: will display a button to clear the history of visited links
# The sidebar header menu.
diff --git a/docs/content/configuration/sidebar/menus/_index.en.md b/docs/content/configuration/sidebar/menus/_index.en.md
index 94d75c07bc..ab1bea5055 100644
--- a/docs/content/configuration/sidebar/menus/_index.en.md
+++ b/docs/content/configuration/sidebar/menus/_index.en.md
@@ -215,7 +215,7 @@ If you want to learn how to configure different Hugo menus for each language, [s
## Defining Sidebar Menus
-{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Menus are defined for individual areas of the sidebar::
+{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Menus are defined for individual areas of the sidebar:
- `sidebarheadermenus`: the non-scrolling area below the search box
- `sidebarmenus`: the scrolling area below the search box
@@ -227,6 +227,7 @@ If you don't set these options in your `hugo.toml`, the theme defaults as follow
- `sidebarheadermenus`:
- a home button if [configured](configuration/sidebar/headerfooter#home-button-configuration), if you redefine this, use a Hugo menu and a `type=menu` to replicate this
+ - the version switcher if versioning is [configured](configuration/sitemanagement/versioning)
- a divider to separate from the `sidebarmenus` (depending on the configuration of the theme variant)
- `sidebarmenus`:
- the main page menu based on your [content structure](authoring/structure)
@@ -286,7 +287,7 @@ A HTML snippet has its own parameter. Your self-defined snippets can contain fur
| Name | Default | Notes |
|-----------------------|-----------------|-------------|
-| **type** | _<empty>_ | The theme ships with the following snippets:
- `languageswitcher`: will display the language switcher
- `variantswitcher`: will display the variant switcher
- `historyclearer`: will display a button to clear the history of visited links |
+| **type** | _<empty>_ | The theme ships with the following snippets:
- `languageswitcher`: will display the language switcher
- `variantswitcher`: will display the variant switcher
- `versionswitcher`: will display the version switcher
- `historyclearer`: will display a button to clear the history of visited links |
| **icon** | see notes | [Font Awesome icon name](shortcodes/icon#finding-an-icon) set to the left of the list entry. Depending on the **type** there is a default icon. Any given value will overwrite the default. |
### Divider
@@ -316,7 +317,6 @@ sidebarmenus = [
sidebarfootermenus = []
{{< /multiconfig >}}
-
## Redefining Sidebar Menus for Certain Pages
Suppose you are building a site that contains a topmost `log` and `ship` section.
diff --git a/docs/content/configuration/sitemanagement/deployment/_index.en.md b/docs/content/configuration/sitemanagement/deployment/_index.en.md
index a78413b6ed..b2a6be3c59 100644
--- a/docs/content/configuration/sitemanagement/deployment/_index.en.md
+++ b/docs/content/configuration/sitemanagement/deployment/_index.en.md
@@ -2,7 +2,7 @@
categories = ["howto"]
description = "Options for specific deployment needs"
title = "Deployment Scenarios"
-weight = 4
+weight = 5
+++
## Offline Usage
diff --git a/docs/content/configuration/sitemanagement/deployment/_index.pir.md b/docs/content/configuration/sitemanagement/deployment/_index.pir.md
index 3c02bce31e..5264d58749 100644
--- a/docs/content/configuration/sitemanagement/deployment/_index.pir.md
+++ b/docs/content/configuration/sitemanagement/deployment/_index.pir.md
@@ -2,6 +2,6 @@
categories = ["howto"]
description = "Options for specific deployment needs"
title = "Deployment Scenarios"
-weight = 4
+weight = 5
+++
{{< piratify >}}
\ No newline at end of file
diff --git a/docs/content/configuration/sitemanagement/meta/_index.en.md b/docs/content/configuration/sitemanagement/meta/_index.en.md
index 991592b3d5..37d1ee0ef1 100644
--- a/docs/content/configuration/sitemanagement/meta/_index.en.md
+++ b/docs/content/configuration/sitemanagement/meta/_index.en.md
@@ -4,7 +4,7 @@ description = "What site-wide meta information can be set"
frontmatter = ["description"]
options = ["author.email", "author.name"]
title = "Meta Information"
-weight = 3
+weight = 4
+++
## Site Author Information
diff --git a/docs/content/configuration/sitemanagement/meta/_index.pir.md b/docs/content/configuration/sitemanagement/meta/_index.pir.md
index 700085244f..61c68ace97 100644
--- a/docs/content/configuration/sitemanagement/meta/_index.pir.md
+++ b/docs/content/configuration/sitemanagement/meta/_index.pir.md
@@ -4,6 +4,6 @@ description = "What site-wide meta information can be set"
frontmatter = ["description"]
options = ["author.email", "author.name"]
title = "Meta Information"
-weight = 3
+weight = 4
+++
{{< piratify >}}
\ No newline at end of file
diff --git a/docs/content/configuration/sitemanagement/outputformats/_index.en.md b/docs/content/configuration/sitemanagement/outputformats/_index.en.md
index d00987be0f..0f0ab6ae7a 100644
--- a/docs/content/configuration/sitemanagement/outputformats/_index.en.md
+++ b/docs/content/configuration/sitemanagement/outputformats/_index.en.md
@@ -3,7 +3,7 @@ categories = ["howto"]
description = "What formats can a page be displayed in"
outputs = ["html", "rss", "print", "markdown", "source"]
title = "Available Output Formats"
-weight = 5
+weight = 6
+++
The Relearn theme by default comes with templates for HTML and RSS for each page.
diff --git a/docs/content/configuration/sitemanagement/outputformats/_index.pir.md b/docs/content/configuration/sitemanagement/outputformats/_index.pir.md
index e7b39e69a0..2d601a004e 100644
--- a/docs/content/configuration/sitemanagement/outputformats/_index.pir.md
+++ b/docs/content/configuration/sitemanagement/outputformats/_index.pir.md
@@ -3,6 +3,6 @@ categories = ["howto"]
description = "What formats can a page be displayed in"
outputs = ["html", "rss", "print", "markdown", "source"]
title = "Available Output Formats"
-weight = 5
+weight = 6
+++
{{< piratify >}}
\ No newline at end of file
diff --git a/docs/content/configuration/sitemanagement/stableoutput/_index.en.md b/docs/content/configuration/sitemanagement/stableoutput/_index.en.md
index 857bd7ad2d..afa1441963 100644
--- a/docs/content/configuration/sitemanagement/stableoutput/_index.en.md
+++ b/docs/content/configuration/sitemanagement/stableoutput/_index.en.md
@@ -3,7 +3,7 @@ categories = ["howto"]
description = "How to make your generated HTML output stable"
options = ["disableAssetsBusting", "disableGeneratorVersion", "disableRandomIds", "minify"]
title = "Stable Output"
-weight = 6
+weight = 7
+++
## Disabling the Generator Meta
diff --git a/docs/content/configuration/sitemanagement/stableoutput/_index.pir.md b/docs/content/configuration/sitemanagement/stableoutput/_index.pir.md
index 62d97a19bf..b1c52a4380 100644
--- a/docs/content/configuration/sitemanagement/stableoutput/_index.pir.md
+++ b/docs/content/configuration/sitemanagement/stableoutput/_index.pir.md
@@ -3,6 +3,6 @@ categories = ["howto"]
description = "How to make your generated HTML output stable"
options = ["disableAssetsBusting", "disableGeneratorVersion", "disableRandomIds", "minify"]
title = "Stable Output"
-weight = 6
+weight = 7
+++
{{< piratify >}}
\ No newline at end of file
diff --git a/docs/content/configuration/sitemanagement/versioning/_index.en.md b/docs/content/configuration/sitemanagement/versioning/_index.en.md
new file mode 100644
index 0000000000..d2e5f6c6a8
--- /dev/null
+++ b/docs/content/configuration/sitemanagement/versioning/_index.en.md
@@ -0,0 +1,124 @@
++++
+categories = ["howto"]
+description = "How to keep older versions of your site"
+options = ["disableVersionWarning", "version", "versionIndexURL", "versions"]
+title = "Versioning"
+weight = 3
++++
+
+{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} The theme offers a way to version your site. This is useful if you want to keep older versions of your site available while also providing links to the current version. Each site version needs to be created separately and is functional independent of each other.
+
+A version switcher will be displayed at the top of the sidebar if versioning is configured. If the user selects a different version, the theme will navigate to the actual page location but in the selected version. If this page does not exist in the selected version, the 404 page will be displayed.
+
+If you want to have more control, where the version switcher is positioned or you want to configure a different icon, see the [chapter on sidebar configuration](configuration/sidebar/menus#defining-sidebar-menus).
+
+## Example: Versioning an Existing Site
+
+Assume, you are writing a documentation for an app. At some point you are a releasing a new major version. This new version requires enhanced documentation while the older documentation must still be available for users of the older app version.
+
+This is your intial `hugo.toml` file:
+
+{{< multiconfig file=hugo >}}
+baseURL = 'https://example.com/'
+{{< /multiconfig >}}
+
+To setup versioning, you have to do the following steps:
+
+1. Prepare your old site for versioning.
+ - add an array of all available `versions` to your `hugo.toml`
+ - add information, which of these versions is the latest by setting the `isLatest` option on **one** item in the `versions` array
+ - add information, which of these versions your site actually is, by setting the `version` option
+ - change your `baseURL` to the version specific URL
+ {{< multiconfig file=hugo >}}
+ baseURL = 'https://example.com/v1.0/'
+ params = { version = 'v1.0', versions = [
+ { identifier = 'v2.0', title = 'Latest', baseURL = 'https://example.com/', isLatest = true },
+ { identifier = 'v1.0', title = 'v1.0', baseURL = 'https://example.com/v1.0/' }
+ ]}
+ {{< /multiconfig >}}
+2. Generate your old site into the `baseURL` (in our case `https://example.com/v1.0/`)
+3. Copy you Hugo project into a new directory
+4. Make changes to the documentation for the new version
+5. Prepare your new site for release.
+ - leave the previously set array of available `versions` as is
+ - change the information, which of the versions your site actually is, by setting the `version` option
+ - change your `baseURL` back to the original URL
+ {{< multiconfig file=hugo >}}
+ baseURL = 'https://example.com/'
+ params = { version = 'v2.0', versions = [
+ { identifier = 'v2.0', title = 'Latest', baseURL = 'https://example.com/', isLatest = true },
+ { identifier = 'v1.0', title = 'v1.0', baseURL = 'https://example.com/v1.0/' }
+ ]}
+ {{< /multiconfig >}}
+6. Generate your new site to the chosen location (in our case `https://example.com/`)
+
+A few things to note here:
+
+- `version` must be an `identifier` of one of the entries in the `versions` array
+- you are not limited with the `baseURL`, these can be absolute or relative to your server root
+- you can generate your old versions into the directory of the new version
+
+## Example: Add New Versions to a Versioned Site
+
+At some point, your version 2 of the app may be deprecated, too, as you've released a new version 3.
+
+You only need to create two versions of your site, the former current one and the new current one.
+
+1. Prepare your old site.
+ - add the new version to the array of available `versions` in your `hugo.toml`
+ - revise information, which of these versions is the latest by setting the `isLatest` option on **one** item in the `versions` array
+ - change your `baseURL` to the version specific URL
+ {{< multiconfig file=hugo >}}
+ baseURL = 'https://example.com/v2.0/'
+ params = { version = 'v2.0', versions = [
+ { identifier = 'v3.0', title = 'Latest', baseURL = 'https://example.com/', isLatest = true },
+ { identifier = 'v2.0', title = 'v2.0', baseURL = 'https://example.com/v2.0/' },
+ { identifier = 'v1.0', title = 'v1.0', baseURL = 'https://example.com/v1.0/' }
+ ]}
+ {{< /multiconfig >}}
+2. Generate your old site into the `baseURL` (in our case `https://example.com/v2.0/`)
+3. Copy you Hugo project into a new directory
+4. Make changes to the documentation for the new version
+5. Prepare your new site for release.
+ - leave the previously set array of available `versions` as is
+ - change the information, which of the versions your site actually is, by setting the `version` option
+ - change your `baseURL` back to the original URL
+ {{< multiconfig file=hugo >}}
+ baseURL = 'https://example.com/'
+ params = { version = 'v3.0', versions = [
+ { identifier = 'v3.0', title = 'Latest', baseURL = 'https://example.com/', isLatest = true },
+ { identifier = 'v2.0', title = 'v2.0', baseURL = 'https://example.com/v2.0/' },
+ { identifier = 'v1.0', title = 'v1.0', baseURL = 'https://example.com/v1.0/' }
+ ]}
+ {{< /multiconfig >}}
+6. Generate your new site to the chosen location (in our case `https://example.com/`)
+
+A few things to note here:
+
+- you **don't need to recreate version 1** of your site as long as the `baseURL` for the entry marked with `isLatest=true` hasn't changed. The old versions will access the version index of the latest site to display all available versions in the version switcher
+
+## Hiding the Deprecation Warning
+
+{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} If visitors navigate to an old version of your site, they will see a deprecation warning at the top of each page.
+
+You can disable it be setting the `disableVersionWarning` option to `true` in your `hugo.toml`.
+
+{{< multiconfig file=hugo >}}
+[params]
+ disableVersionWarning = true
+{{< /multiconfig >}}
+
+## Change URL of the Version Index
+
+{{%badge style="cyan" icon="gears" title=" "%}}Option{{%/badge%}} The default URL for the version index can be changed with the `versionIndexURL` parameter
+
+{{< multiconfig file=hugo >}}
+[params]
+ versionIndexURL = 'myversionindex.js'
+{{< /multiconfig >}}
+
+{{% notice note %}}
+You only need to change these if you have other own content created for those URLs.
+
+Check for duplicate URLs by running `hugo --printPathWarnings`.
+{{% /notice %}}
diff --git a/docs/content/configuration/sitemanagement/versioning/_index.pir.md b/docs/content/configuration/sitemanagement/versioning/_index.pir.md
new file mode 100644
index 0000000000..120a0796a4
--- /dev/null
+++ b/docs/content/configuration/sitemanagement/versioning/_index.pir.md
@@ -0,0 +1,8 @@
++++
+categories = ["howto"]
+description = "How to keep older versions of your site"
+options = ["disableVersionWarning", "version", "versionIndexURL", "versions"]
+title = "Versioning"
+weight = 3
++++
+{{< piratify >}}
\ No newline at end of file
diff --git a/docs/content/introduction/releasenotes/7/6.en.md b/docs/content/introduction/releasenotes/7/6.en.md
index bca723c0fd..5b989df290 100644
--- a/docs/content/introduction/releasenotes/7/6.en.md
+++ b/docs/content/introduction/releasenotes/7/6.en.md
@@ -10,6 +10,8 @@ weight = -6
### New
+- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} The theme [supports versioning](configuration/sitemanagement/versioning) now, were you can keep older versions of your site while showing a version switcher at the top of the menu.
+
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} The menu configuration for the main menu area, [introduced in 7.1.0](introduction/releasenotes/7/1), is extended to the non-scrolling menu header area between search box and main scrolling area using the `sidebarheadermenus` option and to the menu footer area using the `sidebarfootermenus` option.
The [configuration for all sidebar menus](/configuration/sidebar/menus#defining-sidebar-menus) is similar and now comes with two new types of menus.
@@ -20,6 +22,7 @@ weight = -6
- `languageswitcher`: will display the language switcher
- `variantswitcher`: will display the variant switcher
+ - `versionswitcher`: will display the version switcher
- `historyclearer`: will display a button to clear the history of visited links
You don’t need to change anything in your existing installation as the old configuration is used as a default.
diff --git a/docs/i18n/art-x-pir.toml b/docs/i18n/art-x-pir.toml
index c58615a0e3..91dbe6f6f3 100644
--- a/docs/i18n/art-x-pir.toml
+++ b/docs/i18n/art-x-pir.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'You are reading version {{.version}} of this page. The current version can be found here'
+
[Search]
other = "Searrrch"
diff --git a/exampleSite/i18n/art-x-pir.toml b/exampleSite/i18n/art-x-pir.toml
index c58615a0e3..91dbe6f6f3 100644
--- a/exampleSite/i18n/art-x-pir.toml
+++ b/exampleSite/i18n/art-x-pir.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'You are reading version {{.version}} of this page. The current version can be found here'
+
[Search]
other = "Searrrch"
diff --git a/i18n/ar.toml b/i18n/ar.toml
index 67cf0e9631..df5253650d 100644
--- a/i18n/ar.toml
+++ b/i18n/ar.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "rtl"
+[Version-warning]
+other = 'أنت تقرأ الإصدار {{.version}} من هذه الصفحة. يمكن العثور على الإصدار الحالي هنا'
+
[Search]
other = "البحث"
diff --git a/i18n/cs.toml b/i18n/cs.toml
index e1cbef4424..c01d17ea81 100644
--- a/i18n/cs.toml
+++ b/i18n/cs.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Právě si prohlížíte verzi {{.version}} této stránky. Aktuální verzi naleznete tady'
+
[Search]
other = "Hledat"
diff --git a/i18n/de.toml b/i18n/de.toml
index f9b43b343b..f301b61838 100644
--- a/i18n/de.toml
+++ b/i18n/de.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Du liest gerade die Version {{.version}} dieser Seite. Die aktuelle Version finden Sie hier'
+
[Search]
other = "Suchen"
diff --git a/i18n/en.toml b/i18n/en.toml
index f7537a53ee..38ea31fe8c 100644
--- a/i18n/en.toml
+++ b/i18n/en.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'You are reading version {{.version}} of this page. The current version can be found here'
+
[Search]
other = "Search"
diff --git a/i18n/es.toml b/i18n/es.toml
index 85a0f3ab19..c0b556a8d8 100644
--- a/i18n/es.toml
+++ b/i18n/es.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Estás leyendo la versión {{.version}} de esta página. La versión actual se puede encontrar aquí'
+
[Search]
other = "Buscar"
diff --git a/i18n/fa.toml b/i18n/fa.toml
index 480a5fd001..dd6d99ff7f 100644
--- a/i18n/fa.toml
+++ b/i18n/fa.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "rtl"
+[Version-warning]
+other = 'شما در حال خواندن نسخه {{.version}} این صفحه هستید. نسخه فعلی را می توان یافت اینجا'
+
[Search]
other = "جستجو"
diff --git a/i18n/fi.toml b/i18n/fi.toml
index e2ed56e6cb..7b42abaeec 100644
--- a/i18n/fi.toml
+++ b/i18n/fi.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Luet tämän sivun versiota {{.version}}. Nykyinen versio löytyy täällä'
+
[Search]
other = "Etsi"
diff --git a/i18n/fr.toml b/i18n/fr.toml
index f3e9d680f8..47f03d43e5 100644
--- a/i18n/fr.toml
+++ b/i18n/fr.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Vous êtes en train de lire la version {{.version}} de cette page. La version actuelle peut être trouvée ici'
+
[Search]
other = "Rechercher"
diff --git a/i18n/hi.toml b/i18n/hi.toml
index 06396e6f5f..9e2d0eb92c 100644
--- a/i18n/hi.toml
+++ b/i18n/hi.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'आप इस पृष्ठ का संस्करण {{.version}} पढ़ रहे हैं। वर्तमान संस्करण पाया जा सकता है यहाँ'
+
[Search]
other = "खोजे"
diff --git a/i18n/hu.toml b/i18n/hu.toml
index 22de63f18e..b5383d19a0 100644
--- a/i18n/hu.toml
+++ b/i18n/hu.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'A lap {{.version}} verzióját olvasod. Az aktuális verzió megtalálható itt'
+
[Search]
other = "Keresés"
diff --git a/i18n/id.toml b/i18n/id.toml
index 0fba6728af..b2813b9e87 100644
--- a/i18n/id.toml
+++ b/i18n/id.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Anda sedang membaca versi {{.version}} dari halaman ini. Versi saat ini dapat ditemukan sini'
+
[Search]
other = "Telusuri"
diff --git a/i18n/it.toml b/i18n/it.toml
index ac6e906c2d..c5431fdfbb 100644
--- a/i18n/it.toml
+++ b/i18n/it.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Stai leggendo la versione {{.version}} di questa pagina. La versione attuale può essere trovata qui'
+
[Search]
other = "Cerca"
diff --git a/i18n/ja.toml b/i18n/ja.toml
index 1940127985..98e651a754 100644
--- a/i18n/ja.toml
+++ b/i18n/ja.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'このページのバージョン{{.version}}を読んでいます。現在のバージョンを見つけることができますここは'
+
[Search]
other = "検索"
diff --git a/i18n/ko.toml b/i18n/ko.toml
index 6da718fef5..d8c96668d0 100644
--- a/i18n/ko.toml
+++ b/i18n/ko.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = '이 페이지의 {{.version}} 버전을 읽고 계십니다. 현재 버전을 찾을 수 있습니다 여기'
+
[Search]
other = "검색"
@@ -83,15 +86,12 @@ other = "주의"
other = "중요"
[info]
-# 예제 내용상 learn theme 참고 용도로 사용되어 위와 같이 번역합니다.
other = "참고"
[note]
-# code snippent 내의 comment(주석)과의 혼동 방지를 위해 위와 같이 번역합니다.
other = "주"
[tip]
-# 우리말 순화어로 기록 가능하고, note, info와 의미상 좀 더 명확한 구분이 되어 아래처럼 기록합니다.
other = "도움말"
[warning]
diff --git a/i18n/nl.toml b/i18n/nl.toml
index 3c7ba1d552..281da7929b 100644
--- a/i18n/nl.toml
+++ b/i18n/nl.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'U leest versie {{.version}} van deze pagina. De huidige versie is te vinden hier'
+
[Search]
other = "Zoeken"
diff --git a/i18n/pl.toml b/i18n/pl.toml
index 90de2ea65b..fc926e22b0 100644
--- a/i18n/pl.toml
+++ b/i18n/pl.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Czytasz wersję {{.version}} tej strony. Aktualną wersję można znaleźć tu'
+
[Search]
other = "Szukaj"
diff --git a/i18n/pt.toml b/i18n/pt.toml
index 0a2a8a4914..22f9eee586 100644
--- a/i18n/pt.toml
+++ b/i18n/pt.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Você está lendo a versão {{.version}} desta página. A versão atual pode ser encontrada aqui'
+
[Search]
other = "Procurar"
diff --git a/i18n/ro.toml b/i18n/ro.toml
index 14f57c5a5c..fe3df2ca9a 100644
--- a/i18n/ro.toml
+++ b/i18n/ro.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Citiți versiunea {{.version}} a acestei pagini. Versiunea curentă poate fi găsită aici'
+
[Search]
other = "Caută"
diff --git a/i18n/ru.toml b/i18n/ru.toml
index 6f79f388c2..b49e98553f 100644
--- a/i18n/ru.toml
+++ b/i18n/ru.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Вы читаете версию {{.version}} этой страницы. Актуальную версию можно найти здесь'
+
[Search]
other = "Поиск"
diff --git a/i18n/sw.toml b/i18n/sw.toml
index f84715395d..c0c526b6a9 100644
--- a/i18n/sw.toml
+++ b/i18n/sw.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Unasoma toleo {{.version}} la ukurasa huu. Toleo la sasa linaweza kupatikana hapa'
+
[Search]
other = "Tafuta"
diff --git a/i18n/tr.toml b/i18n/tr.toml
index a64525855b..42fbff0135 100644
--- a/i18n/tr.toml
+++ b/i18n/tr.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Bu sayfanın {{.version}} sürümünü okuyorsunuz. Güncel sürüm bulunabilir burada'
+
[Search]
other = "Ara"
diff --git a/i18n/ua.toml b/i18n/ua.toml
index 3218e3b01a..3ec6948d29 100644
--- a/i18n/ua.toml
+++ b/i18n/ua.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Ви читаєте версію {{.version}} цієї сторінки. Актуальну версію можна знайти тут'
+
[Search]
other = "Пошук"
diff --git a/i18n/vi.toml b/i18n/vi.toml
index a11de7cc74..78e5484a7a 100644
--- a/i18n/vi.toml
+++ b/i18n/vi.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = 'Bạn đang đọc phiên bản {{.version}} của trang này. Phiên bản hiện tại có thể được tìm thấy Ở đây'
+
[Search]
other = "Tìm kiếm"
@@ -67,9 +70,6 @@ other = "Menu"
[Toc-toggle]
other = "Mục lục"
-[BinaryPrefix-kilobyte]
-other = "kb"
-
[Byte-symbol]
other = "B"
diff --git a/i18n/zh-CN.toml b/i18n/zh-CN.toml
index 1a9c5c80a2..c642afd651 100644
--- a/i18n/zh-CN.toml
+++ b/i18n/zh-CN.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = '您正在阅读此页面的 {{.version}} 版本。可以找到当前版本这里'
+
[Search]
other = "搜索"
diff --git a/i18n/zh-Hans.toml b/i18n/zh-Hans.toml
index 1a9c5c80a2..c642afd651 100644
--- a/i18n/zh-Hans.toml
+++ b/i18n/zh-Hans.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = '您正在阅读此页面的 {{.version}} 版本。可以找到当前版本这里'
+
[Search]
other = "搜索"
diff --git a/i18n/zh-Hant.toml b/i18n/zh-Hant.toml
index f8b6e1e2c9..c328c79c6d 100644
--- a/i18n/zh-Hant.toml
+++ b/i18n/zh-Hant.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = '您正在閱讀此頁面的 {{.version}} 版本。可以找到當前版本這裡'
+
[Search]
other = "搜尋"
diff --git a/i18n/zh-TW.toml b/i18n/zh-TW.toml
index f8b6e1e2c9..c328c79c6d 100644
--- a/i18n/zh-TW.toml
+++ b/i18n/zh-TW.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = '您正在閱讀此頁面的 {{.version}} 版本。可以找到當前版本這裡'
+
[Search]
other = "搜尋"
diff --git a/i18n/zh.toml b/i18n/zh.toml
index 1a9c5c80a2..c642afd651 100644
--- a/i18n/zh.toml
+++ b/i18n/zh.toml
@@ -1,6 +1,9 @@
[Reading-direction]
other = "ltr"
+[Version-warning]
+other = '您正在阅读此页面的 {{.version}} 版本。可以找到当前版本这里'
+
[Search]
other = "搜索"
diff --git a/layouts/partials/_relearn/defaultSidebarHeader.gotmpl b/layouts/partials/_relearn/defaultSidebarHeader.gotmpl
index 216e0656c4..3df32581c4 100644
--- a/layouts/partials/_relearn/defaultSidebarHeader.gotmpl
+++ b/layouts/partials/_relearn/defaultSidebarHeader.gotmpl
@@ -1,4 +1,6 @@
{{- $defaultmenuconfigs := slice }}
+{{- $defaultconfigelements := slice }}
+
{{- if not site.Params.disableLandingPageButton }}
{{- if (ne site.Params.landingPageURL nil) }}
{{- warnf "UNSUPPORTED usage of 'landingPageURL' config parameter found, remove it and optionally overwrite the `logo.html` partial to provide a link if it should not point to the project's home page; see https://mcshelby.github.io/hugo-theme-relearn/introduction/releasenotes/4/#4-2-0" }}
@@ -23,5 +25,17 @@
))
}}
{{- end }}
+
+{{- $versions := partialCached "_relearn/siteVersions.gotmpl" . }}
+{{- if $versions }}
+ {{- $defaultconfigelements = $defaultconfigelements | append (dict "type" "versionswitcher") }}
+{{- end }}
+
+{{- if $defaultconfigelements }}
+ {{- $defaultmenuconfigs = $defaultmenuconfigs | append
+ (dict "type" "custom" "identifier" "controls" "disableTitle" true "elements" $defaultconfigelements)
+ }}
+{{- end }}
+
{{- $defaultmenuconfigs = $defaultmenuconfigs | append (dict "type" "divider") }}
{{- return $defaultmenuconfigs }}
\ No newline at end of file
diff --git a/layouts/partials/_relearn/siteVersions.gotmpl b/layouts/partials/_relearn/siteVersions.gotmpl
new file mode 100644
index 0000000000..1d4457d925
--- /dev/null
+++ b/layouts/partials/_relearn/siteVersions.gotmpl
@@ -0,0 +1,11 @@
+{{- $versions := slice }}
+{{- range site.Params.versions | default slice }}
+ {{- $version := . }}
+ {{- $isAbs := (urls.Parse .baseURL).IsAbs }}
+ {{- $url := trim .baseURL "/" }}
+ {{- $version = merge $version (dict "isAbs" $isAbs) }}
+ {{- $version = merge $version (dict "value" (.identifier | anchorize)) }}
+ {{- $version = merge $version (dict "baseURL" (cond (or $isAbs (not $url)) $url (print "/" $url))) }}
+ {{- $versions = $versions | append $version }}
+{{- end -}}
+{{- return $versions }}
\ No newline at end of file
diff --git a/layouts/partials/article-content.html b/layouts/partials/article-content.html
index 4e9604c1af..d928e9e2f9 100644
--- a/layouts/partials/article-content.html
+++ b/layouts/partials/article-content.html
@@ -1,4 +1,5 @@
{{/* the following check avoids to print out content of headless bundles if called from nestedContent.gotmpl */}}
{{- if .RelPermalink }}
+{{- partial "content-lead.html" . | safeHTML }}
{{- partial "content.html" . | safeHTML }}
{{- end }}
\ No newline at end of file
diff --git a/layouts/partials/content-lead.html b/layouts/partials/content-lead.html
new file mode 100644
index 0000000000..46835a225b
--- /dev/null
+++ b/layouts/partials/content-lead.html
@@ -0,0 +1,35 @@
+{{- $versions := partialCached "_relearn/siteVersions.gotmpl" . }}
+{{- $pageVersion := site.Params.version | default "" }}
+{{- if and $versions (not $pageVersion) }}
+ {{- warnf "WARNING you have configured `versions` but did not mark this site with a `version`; see https://mcshelby.github.io/hugo-theme-relearn/introduction/releasenotes/7/#7-6-0" }}
+{{- end }}
+{{- $latestVersion := "" }}
+{{- with (where $versions "isLatest" true | first 1) }}
+ {{- range . }}
+ {{- $latestVersion = . }}
+ {{- end }}
+{{- end }}
+{{- with (where $versions "identifier" $pageVersion | first 1) }}
+ {{- range . }}
+ {{- $pageVersion = . }}
+ {{- end }}
+{{- end }}
+{{- if and
+ (not (site.Params.disableVersionWarning | default .Params.disableVersionWarning))
+ (eq (.Store.Get "relearnOutputFormat") "html")
+ $pageVersion
+ $latestVersion
+ (ne $pageVersion.identifier $latestVersion.identifier)
+}}
+ {{- $url := print $latestVersion.baseURL (partial "permalink.gotmpl" (dict "to" .)) }}
+ {{- if not $latestVersion.isAbs }}
+ {{- $url = print (partial "_relearn/relBaseUri.gotmpl" .) $url }}
+ {{- end }}
+ {{- partial "shortcodes/notice.html" (dict
+ "page" .
+ "content" (T "Version-warning" (dict "version" $pageVersion.title "latestUrl" $url ))
+ "icon" " "
+ "style" "warning"
+ "title" " "
+ ) }}
+{{- end }}
\ No newline at end of file
diff --git a/layouts/partials/sidebar/element/versionswitcher.html b/layouts/partials/sidebar/element/versionswitcher.html
new file mode 100644
index 0000000000..17c077f185
--- /dev/null
+++ b/layouts/partials/sidebar/element/versionswitcher.html
@@ -0,0 +1,24 @@
+{{- $versions := partialCached "_relearn/siteVersions.gotmpl" .page }}
+{{- $pageVersion := site.Params.version | default "" }}
+{{- $icon := .element.icon | default "code-branch" }}
+{{- if and $icon (not (findRE ".*?\\bfa-\\w.*?" $icon)) }}
+ {{- $icon = printf "fa-fw fas fa-%s" $icon }}
+{{- end }}
+