How does variable scope work in Hugo for different pages? - hugo

How does variable scope work in Hugo for for different pages?
I can make a list of post titles on my home page by adding this code to themes\[theme name]/layouts/_default/list.html:
<ul>
{{ range .Data.Pages.ByPublishDate }}
<li>
{{ .Title }}
</li>
{{ end }}
</ul>
However the same code in a standalone page content/archive.md produces nothing. How do I get a standalone page to list entries from the /post folder?

the .Data object is scoped to the content type it is called within. To access different type of content use the .Site object on which you can access the .Pages object. That object contains all the pages of all content types. Simply filter for the content type you want using the where function, where .Site.Pages "Type" "post".
So your code becomes:
<ul>
{{ range (where .Site.Pages.ByPublishDate "Type" "post") }}
<li>
{{ .Title }}
</li>
{{ end }}
</ul>

Related

Display 3 most recent blog posts in Hugo (but not other pages)

I have a site with a bunch of static pages, plus a blog, in Hugo.
On the front page, I'd like to create short links to the three most recent blog posts (but not to any possibly recently modified static page). The blog posts are all in directory blog/.
I'm failing to figure out the syntax for this. So far, I have:
{{- range (.Paginate ( first 3 .Pages.ByDate )).Pages }}
<li>{{ .Title }}</li>
{{- end}}
but I need to also filter by directory blog/. This is in my layouts/index.html template.
I'm using Hugo 0.74.3 and this is my solution:
{{ range ( where .Site.RegularPages "Type" "posts" | first 3 ) }}
<li>{{ .Title }}</li>
{{end}}
Note that blog posts with draft: true in their frontmatter are not included.
I started by just iterating over .Site.RegularPages without the where to figure it out
{{ range .Site.RegularPages }}
<h2>{{ . }}</h2>
{{end}}
Hugo is tricky to get the filtering working, but this may work for you
{{ range ( first 3 ( where .Site.Pages "Type" "blog" ).ByDate ) }}
<li>{{ .Title }}</li>
{{ end }}

How to get the first three posts of a specific section in Hugo v0.59?

In Hugo v0.52 I had the following template code that worked to get the posts of the "blog" section on my home page (simplified example):
{{ range where .Pages "Section" "blog"}}
{{ .Title }}
{{ end }}
However, I upgraded to v0.59 and now the functionality is broken. It now only loads my base "blog" page, not the articles. I've looked through the docs and can't find anything to indicate it's changed.
I figured it out right after posting. In v0.59, it needs to be
{{ range where .Site.Pages "Section" "blog"}}
{{ .Title }}
{{ end }}

If statement for taxonomies?

I have a switch and want to add an if statement for taxonomies but don't know how to call it? I tried if .IsTaxonomy but get an error...
{{ if eq .Type "blog" }}
{{ .Title }}
{{ end }}
{{ if eq .Type "help" }}
{{ .Title }}
{{ end }}
{{ if eq .Type "reviews" }}
{{ .Title }}
{{ end }}
{{ if .IsHome }}
home
{{ else if eq .Type "page" }}
{{ .Title }}
{{ end }}
I have a switch and want to add an if statement for taxonomies but don't know how to call it? I tried if .IsTaxonomy but get an error...
The .Type variable that you use with your if statements is something that Hugo gets from the content folder (more precisely the section). So your posts stored in /content/tutorial/ get the tutorial type. You can also set the type of a piece of content by hand. But .Type does not by default equal the content's taxonomy.
An alternative is to use Hugo's .IsNode page variable -- that one always returns true when the current page is a list page. That is, a page with posts from a certain taxonomy or section.
You can inspect the page's .RelPermalink variable to see if the current page contains some taxonomy name (like "reviews"). But I would advise against that, since it isn't a good practice. Any taxonomy change you make or new taxonomy means your theme's code need to be changed. Plus it also requires that you (or your users) never make a spelling mistake with taxonomy names, since else the theme's code breaks.
If I look at your if statements code, the following seems to be the equivalent of what you're trying to do:
{{ if .IsNode }}
<!-- Taxonomy and section list pages -->
{{ .Title }}
{{ else if .IsPage }}
<!-- Content pages -->
{{ else if .IsHome }}
<!-- Homepage -->
home
{{ else }}
<!-- All other pages, like the 404 page -->
{{ end }}

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

Resources