I want to have a list of posts, grouped by year.
My thought to do this was to create a dict where the keys were the years, and the values were a list of pages. I would firstly go through all pages putting them into the dict, and secondly go through the dict and render the page.
My questions:
-
I can create an empty dictionary with {{ $PagesForYear := dict }}
and I could access a particular element if I knew its name at compile-time with $PagesForYear.foo
. However, my key is $year
determined at run-time. Can I do something like {{ $PagesForYear.Set $year "foo" }}
? Alas it doesn’t work.
-
The values would be lists of pages. I can initialize an empty list with {{ $pages = slice }}
. (I also saw array
in an example on the hugo site but didn’t find it in the reference documentation, so I have used slice
so far). Once I’ve initialized my empty list, how do I append new elements to it? {{ $pages.Append "foo" }}
does not work, neither does {{ append $pages "foo" }}
.
If this is documented and I missed it, please excuse me. If you would be so kind as to point me to the documentation, so I can look there next time, I would be much appreciative.
FYI this is the code I have so far (which doesn’t work):
{{ $PagesForYear := dict }}
{{ range .Data.Pages }}
{{ $year := (.Date.Format "2006") }}
{{ $PagesForYear.Set $year (default (slice) ($PagesForYear.Get $year)) }}
{{ ($PagesForYear.Get $year).Append . }}
{{ end }}
{{ range $year, $pages := $PagesForYear }}
<h2>{{ $year }}</h2>
<ul>
{{ range $pages }}
<li>....</li>
{{ end }}
</ul>
{{ end }}
Thanks in advance!
Adrian
Since I just did this recently for my site, maybe this will help save you a little bit of time if it’s similar to the design you’re looking for:
<h1 id="page-top">{{.Section | title}}</h1>
{{ range .Data.Pages.GroupByPublishDate "2006"}}
<h2 class="archive-year" id="{{.Key | urlize}}">{{.Key}}</h2>
<ul>
{{ range sort .Pages "PublishDate" "desc" }}
<li class="content-list-item">
<a href="{{.Permalink}}">
<section>
<header>
{{if gt (len .Title) 60}}
<h3><span class="long-title">{{.Title | markdownify}}</span></h3>
{{else}}
<h3>{{.Title | markdownify}}</h3>
{{end}}
<p>{{ .Description }}</p>
</header>
</section>
</a>
</li>
{{ end }}
</ul>
{{end}}
And then creating a table of contents for maybe a smoothscroll type deal since the {{.TableOfContents}}
won’t help you in the same way as it does in single pages here…
<aside class="toc" id="toc">
<div class="toc-wrapper">
<a class="pagetop-link" href="#page-top">
<header class="toc-header" id="toc-header">
<h4 class="toc-title">Archive</h4>
</header>
</a>
<div class="toc-contents">
<nav id="TableOfContents">
<ul>
<li>
<ul>
{{ range .Data.Pages.GroupByPublishDate "2006"}}
<li><a href="#{{.Key | urlize}}">{{.Key}}</a></li>
{{end}}
</ul>
</li>
</ul>
</nav>
</div>
</div>
</aside>
And then using jQuery and Velocity.js, since velocity will reduce your jank considerably on longer list pages…
$(document).ready(function() {
// bind click event to all internal page anchors
$('.toc a').on('click', function(e) {
// prevent default action and bubbling
e.preventDefault();
e.stopPropagation();
// set target to anchor's "href" attribute
var target = $(this).attr('href');
if (target == "#page-top") {
$(target).velocity('scroll', {
duration: 500,
offset: 0,
easing: 'ease-in-out'
})
} else {
// scroll to each target
$(target).velocity('scroll', {
duration: 500,
offset: -60,
easing: 'ease-in-out'
});
}
});
});