So I just finished writing the first in a series of posts about an Alexa Skill Revamp I'm working on. I know I'm going to write several of these and I wanted each post to be marked with the summary of all the posts as I build them.
For my personal sites (one site - three domains) I use github and a static site generator that I wrote myself - a dotnet tool called Congelato. One of the advantages of this tool is that all the posts are available as strongly typed objects within the context of each page, so I felt that with a little Razor syntax this requirement of tagging a page as part of a series shouldn't be particularly hard.
It wasn't - but I thought I'd share it in case anyone else fancied trying out the tool, or already tried it and wanted the same functionality.
Post Changes
I want each post to be able to add itself to a series, but without making fundamental changes to the site generator. For this I used the post "data" information - a key value pair that all posts have to store extra information that can be useful.
So for any post that's part of a series - they just need to use the name of the series in the data collection
data:
series: Battle Cry Revamp
I also need to be able to identify when the series ends - but without changing any of the previous posts. So the last post in the series is going to also tag itself with an "end" marker. If any of the posts have this marker I know that the series is complete, and I can use that to alter the layout on all pages.
data:
series: Battle Cry Revamp
seriesend: true
Now when a post is part of a series, I want the engine to create a little snippet above the main content. I could have just put conditional logic in the "post" layout I use for all my other posts. But this felt messy, and as layouts can be nested I decided to create a new "series" layout type. So my series posts update their layout to use this layout.
layout: series
Layout Changes
As I've created a new layout page I need to put the series logic in _layouts/series.html
I know that the page I'm rendering with will have a data key of type "series", and so will all the other posts in the same series, and that if the series is complete at least one of the posts will be tagged with "seriesend".
With this information I can create the following start to the layout that gives me the information I need to generate layout with absolutely no specific information about the post itself:
---
layout: default
---
@using System
@using System.Linq
@{var series = Post.Data["series"];}
@{var seriesPosts = Site.Posts.Where(p => p.Data != null && p.Data["series"] == series).Reverse().ToArray();}
@{var seriesEnded = seriesPosts.Any(p => p.Data.ContainsKey("seriesend"));}
<!-- Post Content -->
and then with those variables I can create the snippet at the top of each post telling the reader about the post series, I'm sure this could be tidier but it's what I created for now:
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<p>
This post is @(Array.IndexOf(seriesPosts, Post) + 1) of @(seriesEnded ? seriesPosts.Count().ToString() : "X"), part of the "@series" series</p>
<p>Posts in the series @(seriesEnded ? string.Empty : "<small>I'll udpate the list as I write more</small>"):</p>
@foreach(var post in seriesPosts)
{
<p><a href="@post.Permalink">@post.Title</a></p>
}
</div>
</div>
And that's it
If you use Congelato - I hope this helps.