Sorting JSON data by date in HUGO - hugo

I have the following data structure working in a HUGO site
Data in local appearances.json file:
{
"events":[ {
"name": "title three",
"date": "7/02/2022",
"url": "http://some.com"
},
{
"name": "title one",
"date": "5/01/2022",
"url": "http://some.com"
},
{
"name": "title two",
"date": "7/01/2022",
"url": "http://some.com"
}]
}
Partial page:
<div class="row listrecent">
{{ range .Site.Data.appearances.events }}
{{- partial "list-partials/appearancebox.html" . -}}
{{end}}
</div>
output:
However, I would like to sort the contents of the array by "date", preferably with the newest event at the top - i.e the first block visible should be "title three"
I have tried various sort methods with some success but I cannot seem to combine sorting by date and converting the stringified date.
I could ensure the JSON is in the correct order but that seems fragile to me.

The solution in the end was this:
{{ $events := slice }}
{{ range .Site.Data.appearances.events }}
{{ $event := . }}
{{ $parsedEvent := dict }}
{{ range $k, $v := $event }}
{{ if eq $k "date" }}
{{ $parsedEvent = merge $parsedEvent (dict $k (time $v)) }}
{{ else }}
{{ $parsedEvent = merge $parsedEvent (dict $k $v) }}
{{ end }}
{{ end }}
{{ $events = $events | append $parsedEvent }}
{{ end }}
<div class="row listrecent">
{{ range sort $events "date" "desc" }}
{{ if (.date.After now) }}
{{- partial "list-partials/appearancebox.html" . -}}
{{ end }}
{{end}}
</div>
If anyone has a cleaner way then I am all ears!

Presuming that your json is "events.json", then go for the code below:
<ul>
{{ range sort $json.events "date" "desc" }}
<li>
<b>
{{ .name }}
</b>
<br>
{{ .date }}
</li>
{{ end }}
</ul>
The above solution is working check my branch repo

I'm not near my dev set-up, so this will be psuedo code and concepts, but:
https://gohugo.io/functions/range/#readout <- not very detailed.
https://gohugo.io/functions/sort/#readout <- Much more data.
So, something like:
Authors: {{ range sort .Site.Params.authors }}{{ .firstName }} {{ end }}
(example given in link 2 above).
So concept/psuedo, I believe:
{{ range sort .Site.Data.etc.etc. "date" }}
This would sort by ascending (again, not sure the final output for a date field, also due to the fact I believe you have date as a string, which I understand, it's json, but meaning, it's not going to give you expected output. so you might have to convert that field to a date object or data sortable concept as opposed to a string.
https://gohugo.io/functions/format/#use-local-and-utc
Might be of assistance for that.
Again, not near my compu/dev setup, but the above should work. The key being the sort command.

Related

How to filter post by category in Hugo

how to filter post in Hugo by category taxonomy
I am having three main category like web, Linux and networking and i want to display recent 3 post of the category.
Please someone tell me how to do that.
Last 3 posts from 3 categories
{{ $p := where site.RegularPages "Type" "posts" }}
{{ $p = where $p "Params.categories" "intersect" (slice "web" "Linux" "networking" }}
{{ range first 3 $p }}
<h2>{{ .Title }}</h2>
{{ end }}
Source: https://discourse.gohugo.io/t/list-down-posts-from-multiple-categories/36701
Last 3 posts from 1 category
{{ $p := where site.RegularPages "Type" "posts" }}
{{ $p = where $p "Params.categories" "intersect" (slice "web") }}
{{ range first 3 $p }}
<h2>{{ .Title }}</h2>
{{ end }}
Source: https://discourse.gohugo.io/t/show-posts-by-category-not-working/33690

How to add distinct tags and categories in Hugo?

How can I add distinct tags and categories to create the appropriate template?
Two templates or one with if and else in taxonomy.html?
.Data.Plural in taxonomy.html return "tags" or "categories" so with one test with if. It's good.
{{ if eq .Data.Plural "categories" }}
<div class="alert alert-categories"><h1>{{ .Title }}</h1></div>
{{ end }}
{{ if eq .Data.Plural "tags" }}
<div class="alert alert-tags"><h1>{{ .Title }}</h1></div>
{{ end }}

Looping through selected pages in a relation field

I have a relation field in netlify-cms which prints out my multiple selected related pages. Im struggling to get hugo to go through the loop and grab the title from each page using a combo of range/GetPage.
My broken Example:
{{ range .Params.chassis.availableChassis }}
{{ with .Site.GetPage "/chassis/" . }}<h1>{{ .Title }}</h1>{{ end }}
{{ end }}
Page content:
chassis:
availableChassis:
- Nissan
- Renault
NetlifyCMS field setup:
- {label: "Chassis", name: chassis, widget: object, fields: [
{label: "Available chassis", name: "availableChassis", widget: "relation", collection: "chassis", searchFields: "title", valueField: "title", required: false, multiple: true}
]}
If i do this i get the page title from the page, but obviously its not dynamic based on CMS choice:
{{ with .Site.GetPage "/chassis/nissan" }}<h1>{{ .Title }}</h1>{{ end }}
Possibly an easier solution ive not thought of or im not looking in the right place in the docs.
Created a solution using GetPage, open to alternatives or less chunky solutions
{{ $chassis := .Params.chassis.availableChassis }}
{{ range where .Site.Pages "Type" "chassis" }}
{{ $page := . }}
{{ range $chassis }}
{{ if in $page.Title . }}
{{ with $.GetPage $page.File.Path }}
{{ .Params.hero.heroTitle }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}

Hugo NextInSection with counter

I need to accomplish a layout with a link to next and previous post and a counter marking the actual post, bad representation ahead:
<previousPost 10/100 nextPost>
I put everything to work, except the mention of the current post number:
{{ $posts := (where .Site.RegularPages "Section" "==" "news") }}
{{ $postCount := len $posts }}
{{ $postCount }}
{{ if .PrevInSection }}
Prev Post
{{ end }}
{{ I have no idea }}/{{ $postCount }}
{{ if .NextInSection }}
Next Post
{{ end }}
But I have no clue on how to find the value of the page in the netxInSection context. I'm thinking about changing my code to a range and use the index to mark the current page but I think that should be a smarter way.
Thanks!
After some head banging on the wall I found a way to do it...
{{ range $index, $element := (where .Site.RegularPages "Type" "news" ).Reverse }}
{{ if eq . $ }}
{{- $.Scratch.Set "currentItem" (add $index 1) }}
{{ end }}
{{end}}
{{ $posts := (where .Site.RegularPages "Section" "==" "news") }}
{{ $postCount := len $posts }}
{{ if .PrevInSection }}
prev
{{ else }}
prev
{{ end }}
<div class="page-navigation__counter">
{{ $.Scratch.Get "currentItem" }}/{{ $postCount }}
</div>
{{ if .NextInSection }}
next
{{ else }}
next
{{ end }}

Access content of first "post" of a taxonomy

I try to access the content of the first entry of a Taxonomy. I can get the basic fields like {{.Name}} with the following code:
<ul>
{{ range $key := .Site.Taxonomies.tags.ByCount }}
<li>
{{ with index .Pages 0 }}
{{ .Name }} <-- Name of the first post
{{end}}
{{ .Name }} ({{ .Count }})</li>
{{ end }}
</ul>
But how do I access a custom field of the first content item within the taxonomy?
The fields can be accessed by using {{ .Params }}.

Resources