Special Content Pages

I’d like to create special collection pages that do the following.

  1. Let me create a custom section of content at the top. (think: intro, description, maybe some links or disclaimers)
  2. Automated collection of posts with a certain tag. Preferably with options for me on how to display (alphabetical, chronoligical, reverse-chronological, etc.)

Is this something that’s pretty easy to do, maybe with some light Hugo magic?

1 Like

Yes, this is doable with Hugo a bunch of different ways.

You can see how I do a few versions of this at

All of which do this.

My favorite way to do this is to make a custom layout like:

layouts/thepagename/list.html

Then I put my template there, filtering to the right category or term and organizing it how I want.

Then I make a page that’s empty in:

content/myurlforpage.md

That only has the front matter:

---
title: pagename
type: thepagename
---

That will then make a page at /thepagename.

For example, this makes /letters:

{{define "main" }}
<div class="content list h-feed">
{{$pages := where .Site.Pages "Type" "post" }}
{{$letters := where $pages "Params.categories" "intersect" (slice "letters") }}
  {{ range ($letters.GroupByDate "2006-01").Reverse }}
    {{ $themonth := (time (printf "%s-%s" .Key "01")) }}
    <h1> 
      {{ if lt $themonth.Year "2023" }}
        About Letters
      {{ else }}
        {{ $themonth.Format "2006 - January" }}
      {{ end }}
    </h1>
    {{ range .Pages.Reverse }}
      {{ partial "li.html" . }}
    {{ end }}
    <hr>
 {{ end }}
</div>
{{ end }}

And this is /books:

{{ define "main" }}

{{ $books := $.Site.Data.bookshelves.currentlyreading }}
<div class="singlearea">
 <h1 class="bookshelf-name">Currently Reading</h1>
</div>
<div class="bookshelf">
    {{- range $books }}
      <a href="https://bookshop.org/a/{{ $.Site.Params.bookshop_affiliate_id }}/{{ .isbn }}">
<figure>
   <img 
      class="bookshelf-book-cover"
      src="{{ .cover_url }}"
      alt="{{ .title }} by {{ .author }}"/>
    <figcaption> {{ .title }} by {{ .author }}</figcaption>
</figure>
      </a>
    {{ end }}
</div>

{{- range $shelf, $bookshelf :=  $.Site.Data.bookshelves  }}

{{ if ne $shelf "currentlyreading" }}
<div class="singlearea">
  <h1 class="bookshelf-name">Read in {{ $shelf | replaceRE ".*(20[0-9]{2})$" "$1" }}</h1>
</div>
<div class="bookshelf">
    {{- range $bookshelf }}
  <a href="https://bookshop.org/a/{{ $.Site.Params.bookshop_affiliate_id }}/{{ .isbn }}">
<figure>
  <img 
      class="bookshelf-book-cover"
      src="{{ .cover_url }}"
      alt="{{ .title }} by {{ .author }}"/>
    <figcaption> {{ .title }} by {{ .author }}</figcaption>
</figure></a>
{{ end }}
</div>
{{ end }}
{{ end }}
{{ end }}
3 Likes

Oh nice, this is something I was going to figure out. Thanks!

cc: @Miraz might be good for @custom; looks like an expanded version of Jason’s advice to which you linked last year.

1 Like

Thanks for drawing my attention to this. Appreciate the tip. :grinning:

I’m struggling to get this to work fully, and Im not sure if I am doing something wrong.

Currently I have a customer template at layouts/podcast/list.html and also content/podcast.md which contains the following

---
title: Title
type: podcast
---

However when I go to the page it seems to pull though the title but not the custom layout.

I believe that micro.blog is viewing this as a page rather than list and so using the _default/single template. @jsonbecker

That is correct-- content/podcast.md is not a list page, but a single. You need the template to be layouts/podcast/single.html.

How would I make this a list page like your example above?

You can use range even though it’s a “single” to get all pages. “Single” doesn’t mean it can only access a single page. The example above uses a single template.

Ok thanks.

I miss understood because your example says list.html. I think I get it now

I should update that because it’s wrong :slight_smile: .

Apologies for necro’ing this thread but I’ve been trying to get this working with the following code:

{{ $paginator := .Paginate (union .Site.Taxonomies.categories.catagory1 .Site.Taxonomies.categories.catagory2) 25 }}
{{ range $paginator.Pages  }}

From the following Documentation page over here, but because my page is a ‘single’ page I’m getting an error which says ‘Pages’ is undefined / null reference error as there’s nothing to paginate.

Do you know how I can create a custom ‘list’ page, that only shows some specific categories, instead of a custom ‘single’ page?

Or is this possible with a ‘single’ page and I need a different way to access the variables?

I think you’re problem is not that you’re on a single – which I can do-- but because you are paginating Taxonomies and not pages.

You need to do something like:

{{ $posts := where .Site.Pages "Type" "post" }}
{{ $poststoshow := where $posts "Params.categories" "intersect" (slice "category1" "category2") }}
{{ $paginator := .Paginate $poststoshow }}
{{ range $paginator.Pages }}
1 Like

Hmm, I seem to get a similar error. Any idea what’s up?

Here is a link to what I’m trying with your snippet: theme.snuggle.micro.blog/layouts/embed/single.html at 9c3075e3ad39adbbac6f5a4202dd3c442a084f2c · Snuggle/theme.snuggle.micro.blog · GitHub

Basically, I’m trying to make an ‘embed’ page which is a list of my posts, with one ‘long / pinned’ blog post at the top.

**Theme error:** Error building site: failed to render pages: render of "page" failed: "layouts/embed/single.html:14:27": execute of template failed: template: embed/single.html:14:27: executing "main" at <$paginator.Pages>: error calling Pages: runtime error: invalid memory address or nil pointer dereference

Nothing that jumps out at me.

But to do what you want (highlight a specific post first it seems like?) I would do something… completely different and far simpler.

I’d do something like

{{ $pinned := where .Site.Pages "Params.categories" "pinned" }}
{{ range last 1 $pinned.Pages.ByDate }}
...
{{ end }}

And just put that above your existing list of posts in your index.

That will first list the most recent post with the category pinned, then do all your other posts like normal.

For complex theming adjustments, I highly recommend using the export – theme and Markdown option-- and building locally with Hugo. The fact that you use GitHub suggests you’re sophisticated enough to do that-- the errors will be more informative and way easier/faster to locally debug just using hugo server which will quickly (sub 2 seconds) auto rebuild on save and show you messages as well as autorefresh your browser.

1 Like