Here’s how I added my nifty sidebar in tutorial format!

Iterate over site.posts, which gives you the posts in a reverse chronological order. Then you should deal with the following cases:

  • The first post
    • Start a new year, and a new month.
  • The post’s year and month are equal, or its the first post
    • insert the post (the first post condition is there just in case you haven’t posted for a month! ;) )
  • The post’s year is the same, but the month is different
    • Close the current month, start a new one and insert the post.
  • The post’s year is different
    • Close the current month and year, and start a new year and month, then insert the post.

Then, at the end, store the year and month of the processed post and the loop starts again!

{% assign currentYear = site.time | date: "%Y" %}
{% assign currentMonth = site.time | date: "%B" %}
{% for post in site.posts %}
    
    {% assign postYear = post.date | date: "%Y" %}
    {% assign postMonth = post.date  | date: "%B" %}
    
    {% if forloop.first %}
    <li> {{ postYear}}
        <ul>
            <li> {{ postMonth }}
                <ul>
    {% endif %}
    
    {% if (postYear == currentYear and postMonth == currentMonth) or forloop.first %}
        <li><a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a></li>
    {% endif %}
    
    {% if postYear == currentYear and postMonth != currentMonth %}
        </ul></li>
        <li> {{ postMonth }}
            <ul>
                <li><a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a></li>
    {% endif %}
    
    {% if postYear != currentYear %}
        </ul></li></ul></li>
            <li> {{ postYear}}
                <ul>
                    <li> {{ postMonth }}
                        <ul>
                            <li><a href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a></li>
    {% endif %}
    {% assign currentYear = postYear %}
    {% assign currentMonth = postMonth %}
{% endfor %}

Next you can add some bootstrap collapse magic in order to make the years and months collapsible. If you change the elements with class="collapse" to have class="collapse in" they will be open and not collapsed when the page loads. I used that to have the latest month open up (in the first post condition).

And that’s it! It can be done like this because site.posts gives you the posts in reverse chronological order. It wouldn’t work if you want to order them by tags or something else other than time.