Grouping content on the home page by date and type

I’m developing a blog with two sections: posts and notes. Notes will be published several times a day, whereas posts will appear less frequently. Each content type is formatted differently.

I’m trying to get all content to appear on the home page in reverse chronological order, but would like notes published in succession on the same day to be grouped under a date heading. If a post appears in between that day’s notes, notes should be grouped above and below them. For example:

January 25

Note 5.

Note 4.

Note 3.


Post headline
January 25
Post content.


January 25

Note 2.

Note 1.

I’ve been able to get part of the way there with the code below, which groups all notes under a date heading and publishes any posts above them if they appear.

Post headline
January 25
Post content.


January 25

Note 5.

Note 4.

Note 3.

Note 2.

Note 1.

Any ideas?

{{ range .Site.RegularPages.GroupByDate "January 2, 2006" }}
  {{ range (.Pages.GroupBy "Section") }}

    {{ if eq .Key "posts" }}
      {{ range .Pages }}
        <article class="post">
          <header>
            <h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
            <p>{{ .Date.Format "January 2, 2006" }}</p>
          </header>
          {{ .Content }}
        </article>
      {{ end }}
    {{ end }}

    {{ if eq .Key "notes" }}
      {{ range .Pages.GroupByDate "January 2, 2006" }}
        <h3 class="date">{{ .Key }}</h3>
        {{ range .Pages }}
          <div class="note">
            {{ .Content }}
          </div>
        {{ end }}
      {{ end }}
    {{ end }}

  {{ end }}
{{ end }}

Thanks in advance.

To get both “posts” and “notes” in reverse chronological order, you could add all pages from both of those sections to a variable, then range that variable.

Then for each range (loop) iteration, check the .Type field of the page for whether it’s a post or note, then do something.

Thanks for pointing me in the right direction, zwbetz. The following did the trick:

  • Set variables to capture the post/note date ($day) and content type (prev).
  • Loop through all of the site’s regular pages.
  • If a page is a note, add a date heading if (a) it is the first note with that date or (b) that day’s previous page was a post.

Hope this helps others who come looking!

{{ $day := now.Format "2006-01-02" }}
{{ $prev := "" }}

{{ range .Site.RegularPages }}
  {{ if eq .Type "posts" }}
    <article class="post">
      <header>
        <h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
        <p>{{ .Date.Format "January 2, 2006" }}</p>
      </header>
      {{ .Content }}
    </article>
  {{ end }}
  
  {{ if eq .Type "notes" }}
    {{ if or (ne $day (.Date.Format "2006-01-02")) ((eq $day (.Date.Format "2006-01-02")) | and (eq $prev "posts")) }}
      <h3 class="date">{{ .Date.Format "January 2, 2006" }}</h3>
    {{ end }}
    <div class="note">
      {{ .Content }}
    </div>
  {{ end }}
  
  {{ $day = .Date.Format "2006-01-02" }}
  {{ $prev = .Type }}
{{ end }}
1 Like