How to add distinct tags and categories in Hugo? - 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 }}

Related

Proper way to query in Hugo using goTemplates with multiple nested arguments, is it possible?

I'm working with Hugo and have a question regarding where clause. Currently I am doing the following and it works fine. I attempted to add one more where argument and I got the error below:
Question: How do I add multiple nested arguments to Hugo where clause. I will continue to test it out in the meantime.
Error calling where: can't evaluate the array by no match argument or more than or equal to two arg:uments
Works:
{{ range where (where site.Pages "Type" "post") "Params.type" "featured" }}
<div class="ph1-ns w-50-ns flex">
{{ .Render "li" }}
</div>
{{ end }}
</div>
Fails:
{{ range where (where site.Pages "Type" "post") "Params.type" "featured" "Params.location" "nashville" }}
<div class="ph1-ns w-50-ns flex">
{{ .Render "li" }}
</div>
{{ end }}
</div>
Per Hugo:
Nest where Clauses
You can also nest where clauses to drill down on lists of content by more than one parameter. The following first grabs all pages in the “blog” section and then ranges through the result of the first where clause and finds all pages that are not featured:
I was able to resolve this, after reading some additional information at https://pkg.go.dev/text/template#pkg-overview; I went with the below.
<div class="w-100 flex-ns mhn1-ns flex-wrap mb3">
{{ range where (where site.Pages "Type" "post") "Params.featured" "!=" nil }}
{{ if(eq .Params.location "nashville")}}
<div class="ph1-ns w-50-ns flex">
{{ .Render "li" }}
</div>
{{ else}}
Coming Soon
{{end}}
{{end}}
</div>

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: .Data.Pages works in Blog.html context but fails in another context

In blog.html partial, I have:
{{ range first 1 (where .Data.Pages "Type" "post") }}
<div class="ph1-ns w-50-ns flex">
{{ .Render "li" }}
</div>
{{ end }}
which successfully pulls data for one blog post.
I have another partial comic.html with the exact same code:
{{ range first 1 (where .Data.Pages "Type" "post") }}
<div class="ph1-ns w-50-ns flex">
{{ .Render "li" }}
</div>
{{ end }}
but this fails with the message:
2:18:57 PM: ERROR 2018/08/11 04:18:57 Error while rendering "section": template: /opt/build/repo/site/layouts/section/products.html:3:3: executing "main" at <partial "jumbotron" ...>: error calling partial: template: partials/jumbotron.html:6:11: executing "partials/jumbotron.html" at <partial "comic" .>: error calling partial: template: partials/comic.html:6:19: executing "partials/comic.html" at <where .content.Data....>: error calling where: can't iterate over <nil>
Notes:
blog partial is directly called from index.html using:
{{ partial "blog" . }}
comic partial is indirectly called from index html via jumbotron.html
index.html:
{{ partial "jumbotron" (dict "imageUrl" .Params.image "title" .Title "subtitle") }}
jumbotron.html:
{{ partial "comic" . }}
I suspected this might have been caused by not passing the context to jumbotron, so tried in jumbotron.html:
{{ partial "jumbotron" (dict "imageUrl" .Params.image "title" .Title "subtitle" .Params.subtitle "content" .) }}
and then pulled that context with .content i.e.
{{ range first 1 (where .content.Data.Pages "Type" "post") }}
but this also didn't work. I even tried declaring a variable using .Site.GetPage
and then referencing this variable for the .Data.Pages data, but it didn't work. Any help would be appreciated.

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

AngularJS - Show/hide based on number of items in an ng-repeat

I have an ng-repeat with 2 filters:
<div class="container">
<div ng-repeat-start="addresses in Address.Entries | filter:{IsRegistered: true} | filterDate:'InfoDetails'">
{{ addresses.name }}
{{ addresses.number }}
{{ addresses.email }}
{{ addresses.contact}}
</div>
</div>
How can i add an ng-show or ng-hide to the with class="container" to only show this element if the length of items repeated in the ng-repeat is greater than zero?
You need to assign the filter results to a new variable in order to account for the length of the filtered list.
Then you can use the new variable to show/hide the section.
Working Fiddle
<div class="container" ng-show="filtered.length > 0">
<div ng-repeat-start="addresses
in filtered = (Address.Entries
| filter:{IsRegistered: true}
| filterDate:'InfoDetails')">
{{ addresses.name }}
{{ addresses.number }}
{{ addresses.email }}
{{ addresses.contact}}
</div>
</div>
Try to write a separate function which will send back the true/false (which will determine the ng-show) in your controller.
Something like following,
<div class="container" ng-show="functionToDeterminetheState()">
<div ng-repeat-start="addresses in Address.Entries | filter:{IsRegistered: true} | filterDate:'InfoDetails'">
{{ addresses.name }}
{{ addresses.number }}
{{ addresses.email }}
{{ addresses.contact}}

Resources