Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ go/**

# archived site version
archived_version

# Local Netlify folder
.netlify
25 changes: 23 additions & 2 deletions data/versions.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# The version of Istio currently documented in istio.io
main: "1.26"

# The version of Istio currently documented in preliminary.istio.io
preliminary: "1.27"

# List of all versions to be included in the dropdown selector and for archive logic
versions:
- id: "1.26" # Version number
path_segment: latest # URL path for this version on istio.io
display_name: "v1.26 (Latest)" # Text in dropdown
status: latest # Status identifier
- id: "1.25"
path_segment: v1.25 # URL path for this archived version
display_name: "v1.25"
status: archive
- id: "1.24"
path_segment: v1.24
display_name: "v1.24"
status: archive
- id: "1.23"
path_segment: v1.23
display_name: "v1.23"
status: archive
- id: "1.22"
path_segment: v1.22
display_name: "v1.22"
status: archive
87 changes: 84 additions & 3 deletions layouts/partials/header.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
{{ $home := .Site.GetPage "home" }}
{{ $section := .Section }}
{{ $current := . }}

{{/* --- Version Logic (needed for JS and conditional dropdown) --- */}}
{{ $versionsData := site.Data.versions }}
{{ $currentVersionIDFromParams := .Site.Params.currentVersionId | default ($versionsData.latest_version | default "") }}
{{ $latestVersionID := $versionsData.latest_version | default "" }}

{{/* Calculate currentPathSegment - needed by navigateToVersionSimple JS function */}}
{{ $currentPathSegment := "" }}
{{ range $versionsData.versions }}{{ if eq .id $currentVersionIDFromParams }}{{ $currentPathSegment = .path_segment }}{{ end }}{{ end }}


<header class="main-navigation {{ if .IsHome }}main-navigation--transparent{{ end }}">
<nav class="main-navigation-wrapper container-l">
Expand All @@ -23,7 +31,30 @@
{{ $currentPage := .}}
{{ range .Site.Menus.main }}
{{ $active := or (eq $currentPage.Title .Name) (or ($currentPage.HasMenuCurrent "main" .) ($currentPage.IsMenuCurrent "main" .)) }}
{{ if .HasChildren }}

{{ if eq .Name "Documentation" }}
<li class="main-navigation-links-item">
<a href="{{ .URL | relLangURL }}" class="main-navigation-links-link {{ if and $versionsData }}has-dropdown{{ end }} {{ if $active }}active{{ end }}">
<span>{{ .Name }}</span>
{{ partial "icon.html" "dropdown-arrow" }}
</a>

{{ if and $versionsData }}
<ul class="main-navigation-links-dropdown">
{{ range $versionsData.versions }}
<li class="main-navigation-links-dropdown-item">
<a href="javascript:void(0);"
data-pathsegment="{{ .path_segment }}"
onclick="navigateToVersionSimple(this.dataset.pathsegment); return false;"
class="main-navigation-links-link {{ if eq .id $currentVersionIDFromParams }}active-version-link{{ end }}">
{{ .display_name }}
</a>
</li>
{{ end }}
</ul>
{{ end }}
</li>
{{ else if .HasChildren }}
<li class="main-navigation-links-item">
<a {{ if ne .URL "" }}href="{{ .URL | relLangURL }}"{{end}} class="main-navigation-links-link has-dropdown {{ if $active }}active{{ end }}">
<span>{{ .Name }}</span>
Expand Down Expand Up @@ -71,3 +102,53 @@
</form>
</nav>
</header>

<script>
Copy link
Contributor

Choose a reason for hiding this comment

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

this should eventually end up in its own TS file.

function navigateToVersionSimple(selectedVersionPathSegment) {
const currentFullPath = window.location.pathname;
const currentVersionPathSegment = {{ $currentPathSegment | jsonify }};
const selectedTargetSegment = selectedVersionPathSegment;

if (!currentVersionPathSegment && currentVersionPathSegment !== "" ) {
const fallbackBase = selectedTargetSegment === 'latest' ? '/latest/' : ('/' + selectedTargetSegment + '/');
window.location.href = fallbackBase;
return;
}

let contentPath = '';
let foundContent = false;
const knownContentPrefixes = ['docs/', 'blog/', 'news/', 'about/', 'faq/', 'operations/', 'tasks/', 'reference/', 'concepts/', 'samples/', 'download/', 'search/'];

for (const prefix of knownContentPrefixes) {
const index = currentFullPath.indexOf('/' + prefix);
if (index > -1) {
contentPath = currentFullPath.substring(index + 1);
foundContent = true;
break;
}
}

if (!foundContent) {
const currentBaseForCheck = currentVersionPathSegment === 'latest' ? '/latest/' : '/' + currentVersionPathSegment + '/';
if (currentFullPath === '/' || currentFullPath === currentBaseForCheck || currentFullPath === currentBaseForCheck.slice(0,-1)) {
contentPath = '';
} else {
contentPath = 'docs/'; // Default to docs root of target version
}
}

let newBase = selectedTargetSegment === 'latest' ? '/latest/' : ('/' + selectedTargetSegment + '/');
// Ensure newBase ends with a slash if contentPath is not empty or already starts with one
if (contentPath !== "" && !newBase.endsWith('/')) {
newBase += '/';
}
if (contentPath.startsWith('/')) { // Avoid double slash if contentPath accidentally starts with /
contentPath = contentPath.substring(1);
}

let finalUrl = newBase + contentPath;
finalUrl = finalUrl.replace(/\/\//g, '/'); // Replace double slashes

window.location.href = finalUrl;
}
</script>
4 changes: 4 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@
[headers.values]
X-Frame-Options = "SAMEORIGIN"
X-XSS-Protection = "1; mode=block"

[[edge_functions]]
path = "/v*"
function = "redirect-to-latest"
14 changes: 14 additions & 0 deletions netlify/edge-functions/redirect-to-latest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default async (request: Request) => {
const url = new URL(request.url);

// Match paths starting with "/v" followed by a version number pattern
// Excludes paths containing "/docs/"
if (url.pathname.match(/^\/v\d+(\.\d+)*/) && !url.pathname.includes('/docs/')) {
// Preserve the rest of the path after the version part
const newPath = url.pathname.replace(/^\/v\d+(\.\d+)*/, '/latest');

return Response.redirect(new URL(newPath, url.origin), 301);
}

return fetch(request);
};