Ranging through sorted data

I am trying to show a list of archive “boxes” that are filled via data file.

archive.yaml:

2005:
  slug: 2005
  title: 2005
  description: tbd
  buttontext: Zum 2005er Archiv
2006:
  slug: 2006
  title: 2006
  description: tbd
  buttontext: Zum 2006er Archiv
... etc etc

In a shortcode then this data get’s traversed:

<div class="card-deck mb-3">
{{ range $index, $item := .Site.Data.archive }}
	<div class="card">
		<div class="card-header">{{ $item.title }}</div>
		<div class="card-body">
			<p>{{ $item.description }}</p>
			<a href="/archiv/{{ $item.slug }}/" class="btn btn-primary">{{ $item.buttontext }}</a>
		</div>
	</div>
    {{ if modBool $index 3 }}
</div><div class="card-deck mb-3">
    {{ end }}
{{ end }}
</div>

The problem I am experiencing is that the resulting output is ordered by the index (year) ASCENDING whatever order I use in my data. How do I sort the data array DESCENDING before ranging through it?

The sort command documentation does not show how to sort a range with an index in it (every three boxes there needs to be a line break). Maybe that would be a nice example to extend the docs.

Try this:

{{ range $index, $item := sort .Site.Data.archive ".slug" "desc" }}

But keep in mind this note from the docs:

A sorted array of map values will be returned with the keys eliminated.

Thank you, that worked well. I had to “hack” the “every three boxes” part a little bit:

<div class="card-deck mb-3">
{{ range $index, $item := sort .Site.Data.archive ".slug" "desc" }}
	<div class="card">
		<div class="card-header">{{ $item.title }}</div>
		<div class="card-body">
			<p>{{ $item.description }}</p>
			<a href="/archiv/{{ $item.slug }}/" class="btn btn-primary">{{ $item.buttontext }}</a>
		</div>
	</div>
    {{$index2 := add $index 1}}
    {{ if mod $index2 3 | eq 0 }}
</div><div class="card-deck mb-3">
    {{ end }}
{{ end }}
</div>

See this thread: Ranging over collection of data files with an explanation about the underlying concepts of maps (not sortable) and arrays (sortable).

Maybe try this approach:

  • build a first array of the indexes of your data, the key array
  • sort this array as you like: asc, describe, filter, whatever
  • range over this sorted array and use these values to pull data from the original map by index
1 Like