Hugo NextInSection with counter - hugo

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

Related

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 - Access .Pages from the context of the list template from within the context of the single template

The documentation for hugo says the the .Pages variable inside the context of the single page is blank and that the .Pages variable from the context of the list page is populated.
I want to access the .Pages variable from the list page INSIDE the context of the single page.
How do I do this?
Documentation is below:
Worked through the issue here is what I came up with. This snippet:
{{ $currentPage := . }}
{{ range .Site.Pages }}
{{ if .InSection $currentPage}}
{{ if .IsAncestor $currentPage }}
{{ else }}
<li>
<a class="nav-link active" href="{{.Permalink}}">{{.Title}}</a>
</li>
{{ end }}
{{ end }}
{{ 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 }}.

Concatenate variable in Hugo

This snippet works wonderfully on Hugo:
{{ if and (or .IsPage .IsSection) .Site.Params.contentCommitsURL }}
{{ $File := .File }}
{{ $Site := .Site }}
{{with $File.Path }}
Link to API call
{{ end }}
{{ end }}
With,
[Params]
contentCommitsURL = https://api.github.com/repos/csitauthority/CSITauthority.github.io/commits?path=HUGO/content/
it is able to beautifully generate the following link
Link to API call
in the layout html file.
Problem Description
The URL is generated. Now I'm pulling hairs trying to figure out how to concatenate the commands { $Site.Params.contentCommitsURL }}{{ replace $File.Dir "\\" "/" }}{{ $File.LogicalName }} in a page variable such as {{ $url }}
For instance:
{{ $url := {{ $Site.Params.contentCommitsURL }}{{ replace $File.Dir "\\" "/" }}{{ $File.LogicalName }} }}
does not work
but the following does:
{{ $url := "https://api.github.com/repos/csitauthority/CSITauthority.github.io/commits?path=HUGO/content/post/vlan-101.md"}}
I want to be able to do something like this:
{{ $url := $Site.Params.contentCommitsURL + (replace $File.Dir "\\" "/") + $File.LogicalName }}
^Obviously, that doesn't work. I want to know what does.
On the Hugo discourse forum, someone hinted a solution and I was able to come up with the following.
{{ if and (or .IsPage .IsSection) .Site.Params.contentCommitsURL }}
{{ $File := .File }}
{{ $Site := .Site }}
{{with $File.Path }}
{{ $fileDir := replace $File.Dir "\\" "/"}}
{{ $url := $File.LogicalName | printf "%s%s" $fileDir | printf "%s%s" $Site.Params.contentCommitsURL }}
{{ $.Scratch.Set "url" $url }}
{{ end }}
{{ end }}
Where I want it to appear, I use the Scratch function like this:
{{ $url := $.Scratch.Get "url"}}
{{ range getJSON $url }}
<div style="display:inline-block; width:40px;"><a href="{{.author.html_url}}" target="_blank">
<img src="{{.author.avatar_url}}" alt="{{.author.login}}" text="{{.author.login}}" class="inline" width="40" height="40" style="height: 40px;height: 40px; vertical-align:middle; margin: 0 auto;"></a>
</div>
{{ end }}
The code is self-explanatory so I won't bother with a verbose description. Instead, I'd like to bring your focus on the implementation. You'll notice that the Scratch function has been used.
The hugo documentation says this:
Variables defined inside if conditionals and similar are not visible on the outside.
(see this issue)
It's a workaround that involves storing the value temporarily. here's more on scratch
Limitations
As of this moment, I feel this code is not complete. It works but, it shows the author based on commits. So multiple commits will generate the same author multiple times. I bring this limitation to your notice, to develop a creative solution. I'll update this answer when I get a satisfactory answer. Meanwhile, feel free to suggest.
here's my original answer on hugo discourse.

How to List Pages in Current Section

I'm trying to list the pages in the current url section.
Get All Sections
Limit range to current Section
List pages in current Section
{{ range $value := .Site.Sections }}
{{ range .Section }}
{{ range $value.Pages }}
<ul>
<li>{{ .Title }}</li>
</ul>
{{ end }}
{{ end }}
{{ end }}
Though it returns null because {{ range .Section }} is not valid code.
What is the correct way to do this?
https://gohugo.io/templates/variables/
You need to filter .Site.Pages by section using the where function. Try this:
<ul>
{{ range where .Site.Pages "Section" .Section }}
<li>{{ .Title }}</li>
{{ end }}
</ul>
If you want to avoid empty lists, you can store the slice of section pages in a variable and check its length before you output the ul tags.
{{ $sectionPages := where .Site.Pages "Section" .Section }}
{{ if ge (len $sectionPages) 1 }}
<ul>
{{ range $sectionPages }}
<li>{{ .Title }}</li>
{{ end }}
</ul>
{{ end }}

Resources