List blog posts in all languages, but no duplicates

I have a multilingual site where I usually post in English but sometimes I’ll have a post in Dutch as well. I also have some posts that I wrote in both languages (index.md and index.nl.md).
I want to list my most recent blog posts in either languages. But doing so, I don’t want a translated article to pop up twice.

So far, I’ve come up with the following template to show me the most recent posts in any language:

<ul>
    {{ range where (where .Site.AllPages "Section" "==" .Params.section) "Kind" "==" "page" | first .Params.limit }}
        <li class="bullet">
            <a href="{{ .RelPermalink }}" title="{{ .Title }}" hreflang="{{ .Language.Lang }}">{{ .LinkTitle }}</a>
        </li>
    {{ end }}
</ul>

I 'm using AllPages since that will collect pages from all languages, where RegularPages would only show you pages in your current language.
Because of that, I need to filter out the page kind, otherwise it’ll also show e.g. the section page.

There’s a filter on section here as well, as I tried to make the filter dynamic so that I can select different sections if I wanted to. But for testing this could be hardcoded to e.g. blog.

content/
├─ blog/
│  ├─ topic 1/
│  │  ├─ index.md     <-- English
│  │  ├─ index.nl.md  <-- Dutch
│  ├─ topic 2/
│  │  ├─ index.md     <-- English
│  ├─ topic 3/
│  │  ├─ index.nl.md  <-- Dutch

The resulting list is

- topic 1   <--- English version
- topic 1   <--- Dutch version
- topic 2   <-- English
- topic 3   <-- Dutch

While I would like to get

- topic 1   <--- current site language version
- topic 2   <-- English
- topic 3   <-- Dutch

A simplified version of my full menu template is:

<nav>
    <ul class="sidebar-nav">
        {{- range .Site.Menus.main.ByWeight }}
            <li class="heading">
                <a href="{{ .URL }}" title="{{ or .Title .Name }}" {{- with .Params.rel }} rel="{{ . }}"{{ end -}}>
                    {{ .Name }}
                </a>
            </li>
            {{ if .Params.section }}
                {{ with .Pre }}
                    <li class="sub-heading">
                        {{ . }}
                    </li>
                {{ end }}
                {{ range where (where $.Site.AllPages "Section" "==" .Params.section) "Kind" "==" "page" | first .Params.limit }}
                    <li class="bullet">
                        <a href="{{ .RelPermalink }}" title="{{ .Title }}" hreflang="{{ .Language.Lang }}">{{ .LinkTitle }}</a>
                    </li>
                {{ end }}
            {{ end }}
        {{ end }}
    </ul>
</nav>
menus:
  main:
    - name: About
      pageRef: /about/
      weight: 10
    - name: Blog
      pageRef: /blog/
      weight: 20
      pre: Recent
      params:
        section: blog
        limit: 3
{{/* Get pages from current site. */}}
{{ $p := where .Site.RegularPages "Section" "blog" }}

{{/* Add pages from other sites. */}}
{{ range complement (slice .Site) .Site.Sites }}
  {{ $p = $p | lang.Merge (where .RegularPages "Section" "blog") }}
{{ end }}

{{/* Render list. */}}
{{ range $p.ByDate.Reverse }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}

https://gohugo.io/functions/lang/merge/

The above works with any number of languages with precedence based on language weight.

3 Likes

So simple, once you see it :slight_smile:

Thanks again for your lightning fast support!

Had to use $ for context since this was within a range of the menu items.
Also added the limit again.

Final result: poison/layouts/partials/sidebar/menu.html at 083fc4ddd849ad65e1bfe370d948496afa847114 · TheGroundZero/poison · GitHub

<nav>
    <ul class="sidebar-nav">
        {{- range .Site.Menus.main.ByWeight }}
        <!-- ... snip for brevity ... -->
            {{ if .Params.section }}
                {{ with .Pre }}
                    <li class="sub-heading">
                        {{ . }}
                    </li>
                {{ end }}
                {{ $s := .Params.section }}
                {{/* Get pages from current site. */}}
                {{ $p := where $.Site.RegularPages "Section" $s }}
                {{/* Add pages from other sites. */}}
                {{ range complement (slice $.Site) $.Site.Sites }}
                    {{ $p = $p | lang.Merge (where .RegularPages "Section" $s) }}
                {{ end }}
                {{/* Render list. */}}
                {{ range $p.ByDate.Reverse | first .Params.limit }}
                    <li class="bullet">
                        <a href="{{ .RelPermalink }}" title="{{ .Title }}" hreflang="{{ .Language.Lang }}">{{ .LinkTitle }}</a>
                    </li>
                {{ end }}
            {{ end }}
        {{ end }}
    </ul>
</nav>

Also made a multilingual version of the main menu using menus.en.yaml and menus.nl.yaml.

/* menus.en.yaml */
main:
  - name: About
    pageRef: /about/
    weight: 10
  - name: Blog
    pageRef: /blog/
    pre: Recent
    weight: 20
    params:
      section: blog
      limit: 3
  - name: Shopping
    pageRef: /shoppinglist/
    weight: 30
  - name: Privacy
    pageRef: /privacy/
    weight: 40

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.