Exclude pages by "type" from 'NextInSection'

I use something like this to turn pages, in a partial:

<div class="screen">
    <ul class="umblaettern">
        <li>{{if .PrevInSection}}
            <a href="{{.PrevInSection.RelPermalink}}"><<< next article</a>
            {{end}}</li>
        <li>{{if .NextInSection}}
            <a href="{{.NextInSection.RelPermalink}}">previous article >>></a>
            {{end}}</li>
    </ul>
</div>

Now I have pages marked by a page parameter and these pages should be excluded.
Page frontmatter:

type = "teaser"

I can’t find a way to do that, i. e.

        <li>{{if .NextInSection}}
            {{ if ne "Type" "teaser" }}
            <a href="{{.NextInSection.RelPermalink}}">next article >>></a>
            {{end}}
            {{end}}</li>

does not show any effect, neither does

            {{ if ne .Params.Type "teaser" }}

instead.

Obviously I have to examine, if the front matter of the next page contains the “type” frontmatter, but my partial seems to examine the current page …

Is there a way to do this right?

If you want the next page in the section which does not have a certain value for a parameter, you may need to use a recursive partial. This is because .NextInSection is not a collection that you can filter, but just a single page.

Here’s an example of how you could create a recursive partial

// in the base template

{{ partial "nextpage" . }}
// in /layouts/partials/nextpage.html

{{ with .NextInSection }}
  // Check if the next page is a teaser
  {{ if eq .Params.Type "teaser" }}
    // if so, try the next next page (this creates recursion)
    {{ partial "nextpage" . }}
  {{ else }}
    // otherwise render the next page link
    <a href="{{ .RelPermalink }}"> Next Page </a>
  {{ end }}
{{ end }}

You can filter using where and then

1 Like

Thanks for this - I got it to work easily - and as my teaser pages are “at the end” of the list because of hugos default sorting by weight/date/name (teaser pages having associated weight - other pages in the blog section do not) I could do without the recursion in this case

I tried many things to get this to work - no success.

{{ range .Site.Pages  }}

gives all pages, not only the ones of the blog section (as expected).

{{ range .Data.Pages  }}

doesn’t give any pages …

I then tried to do something like - in words “range .Site.Pages where section blog and type ne ‘teaser’” in many different ways but hugo kept complaining about wrong number of arguments etc. … til I gave up.

Adding to the thread because @bep’s reply got me halfway to solving a similar .Next confusion.

First, build the collection of pages you care about with nested where filters:

{{ $pages := where (where .Site.RegularPages "Section" .Section) "Type" "!=" "teaser" }}

Then, use that collection’s .Next and .Prev methods with the current context:

{{ with $pages.Prev . }} ... {{ end }}
{{ with $pages.Next . }} ... {{ end }}

This way we don’t have to care about recursive partials.

2 Likes