Looping through selected pages in a relation field - hugo

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 }}

Related

Sorting JSON data by date in 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.

Hugo cannot convert type page.PagesGroup to Pages

I have a Hugo list template like this:
{{ range (.Paginate (.Data.Pages.GroupByDate "2006")).PageGroups }}
<h3>{{ .Key }}</h3>
<ul>
{{ range .Pages.ByWeight }}
<li>
{{ if .Draft }}{{ T "draft" }}: {{end}}{{ .Title | markdownify }}
<time class="date-meta">{{ .Date.Format "Jan 2" }}</time>
</li>
{{ end }}
</ul>
{{ end }}
When I run the site like this hugo server -D it works fine.
When I build the site I get:
execute of template failed: template: _default/list.html:15:14: executing "main" at <.Paginate>: error calling Paginate: cannot convert type page.PagesGroup to Pages
Turning on debug and verbose do not help. I have:
content
content/web
content/web/one.md
content/web/two.md
content/web/_index.md
content/web/three.md
content/about
content/about/index.md
What gives?
I encountered this error while writing a custom theme except it happened when running hugo -D or hugo server -D. As a workaround try wrapping it in an if condition to check .Data.Pages.
{{ if .Data.Pages }}
{{ range (.Paginate (.Data.Pages.GroupByDate "2006")).PageGroups }}
...
{{ end }}
{{ end }}

Hugo v0.55.x Deprecation Errors - ".File.BaseFileName" on zero object

I've been experimenting with finding a fix for a new deprecation error that occurs with Hugo version 0.55.5:
.File.BaseFileName on zero object. Wrap it in if or with: {{ with .File }}{{ .BaseFileName }}{{ end }}
The two affected snippets of code in question:
{{ $header := print "_header." .Lang }}
{{ range where .Site.Pages "File.BaseFileName" $header }}
{{ .Content }}
{{else}}
{{ if .Site.GetPage "page" "_header.md" }}
{{(.Site.GetPage "page" "_header.md").Content}}
{{else}}
<a class="baselink" href="{{.Site.BaseURL}}">{{.Site.Title}}</a>
{{end}}
{{end}}
&& the footer:
{{ $footer := print "_footer." .Lang }}
{{ range where .Site.Pages "File.BaseFileName" $footer }}
{{ .Content }}
{{else}}
{{ if .Site.GetPage "page" "_footer.md" }}
{{(.Site.GetPage "page" "_footer.md").Content}}
{{end}}
{{end}}
I've been attempting different variations of wrapping those segments of code with {{ with .File }} as the error message suggests, but it isn't liking anything I've been coming up with. As an example, if I put that surrounding bit of code around the {{ range ... }} statement, I get the error: can't evaluate field Site in type source.File. If someone could assist in figuring out where {{ with .File }} should be placed, it would be greatly appreciated.
You get this error
can't evaluate field Site in type source.File
Because the context changes when inside with. To fix it, wrap your code in a {{ with .File }} as you mentioned.
Then everywhere you're using .Site, replace it with site.
Then make sure you're using Hugo version 0.53.0 or higher, so that the site keyword is available.

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