Skip to content

Instantly share code, notes, and snippets.

@rordi
Last active April 18, 2021 18:33
Show Gist options
  • Save rordi/eab8606b377638eeaa984367bde0a2d0 to your computer and use it in GitHub Desktop.
Save rordi/eab8606b377638eeaa984367bde0a2d0 to your computer and use it in GitHub Desktop.
Previous / Next Navigation in Hugo with custom section order

Previous/Next navigation in Hugo with custom order based on param / attribute

This gist let's you return previous/next pages based on a frontmatter parameter in Hugo. In this exmaple, the frontmatter parameter is called position, where lower positions come first.

This prev / next navigation is looping: if there is no "next >" entry anymore, the first entry of the collection will be linked. Same for "< prev": if there is no previous element, the last element of the collection will be linked.

<div class="nav-prev-next">
    {{ $currentSection := (($.Site.GetPage "section" .Section).Pages.ByParam "position") }}

    {{ $.Scratch.Set "counter" 0 }}
    {{ $.Scratch.Set "currentPosition" 0 }}

    {{/* calculate current position in array */}}
    {{ range $currentSection }}
        {{ if eq $.Permalink .Permalink }}
            {{ $.Scratch.Set "currentPosition" ($.Scratch.Get "counter") }}
        {{ end }}
        {{ $.Scratch.Set "counter" (add ($.Scratch.Get "counter") 1) }}
    {{ end }}


    {{/* get Permalink for element before and after current position in array */}}
    {{ $.Scratch.Set "counter" 0 }}
    {{ range $currentSection }}
        {{/* next is at current position + 1 */}}
        {{ if eq ($.Scratch.Get "counter") (add ($.Scratch.Get "currentPosition") 1) }}
            {{ $.Scratch.Set "next" .Permalink }}
        {{ end }}

        {{/* prev is at current position - 1 */}}
        {{ if eq ($.Scratch.Get "counter") (sub ($.Scratch.Get "currentPosition") 1) }}
            {{ $.Scratch.Set "previous" .Permalink }}
        {{ end }}

        {{ $.Scratch.Set "counter" (add ($.Scratch.Get "counter") 1) }}
    {{ end }}
    
    
    {{/* prints the '< prev' link - remove the else block if you do not want to link the last entry if there is no previous entry */}}
    {{ if $.Scratch.Get "previous" }}
        <a href="{{ $.Scratch.Get "previous" }}" class="nowrap nav-prev" aria-label="Previous entry">
	        <img src="/images/uploads/angle.svg" alt="Previous entry" />
	    </a>
    {{ else }}
        {{range last 1 $currentSection }}
            <a href="{{ .Permalink }}" class="nowrap nav-prev" aria-label="Previous entry">
	            <img src="/images/uploads/angle.svg" alt="Previous entry" />
            </a>
        {{ end }}
    {{ end }}


    {{/* print the 'next >' link - remove the else block if you do not want to link the first entry if there is no next entry */}}
    {{ if $.Scratch.Get "next" }}
        <a href="{{ $.Scratch.Get "next" }}" class="nowrap nav-next" aria-label="Next entry">
	        <img src="/images/uploads/angle.svg" alt="Next entry" />
        </a>
    {{ else }}
        {{ range first 1 $currentSection }}
            <a href="{{ .Permalink }}" class="nowrap nav-next" aria-label="Next entry">
	            <img src="/images/uploads/angle.svg" alt="Next entry" />
            </a>
        {{ end }}
    {{ end }}
</div>
@inwardmovement
Copy link

I have a shorter version here, I think it does simpler what you say (the parameter is recueil).

It was working in 0.54 but not anymore in 0.55, if you have any clue why I'd be glad if you could help, otherwise I will try your code, but it's way more complicated.

@cmmartti
Copy link

Here's a simplified solution using the front matter parameter chapter, without looping:

{{- $pages := ($.Site.GetPage "section" .Section).Pages.ByParam "chapter" }}
{{- $.Scratch.Set "curPosition" 0 }}
{{- $.Scratch.Set "index" 0 }}
{{- range $pages }}
  {{- if eq $ . }}
    {{- $.Scratch.Set "curPosition" ($.Scratch.Get "index") }}
  {{- end }}
  {{- $.Scratch.Add "index" 1 }}
{{- end }}
{{- $next := (index $pages (add ($.Scratch.Get "curPosition") 1)) }}
{{- $prev := (index $pages (sub ($.Scratch.Get "curPosition") 1)) }}

{{- with $prev }}
<a href="{{ .Permalink }}">← {{ .Params.chapter }}. {{ .Title }}</a>
{{- end }}

{{- with $next }}
<a href="{{ .Permalink }}">{{ .Params.chapter }}. {{ .Title }} →</a>
{{- end }}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment