Mastodon

Creating a blog archive page in Jekyll

May 10, 2021 by Kolappan N

In this post, I’ll explain about creating a archive page for your blog that arranges post by the published year. Creating a archive page in Jekyll is quite easy. Jekyll stores all your blog post related information in site.posts, which we will use to generate the archive.

Basic Loop

First we’ll start with a simple for loop of all the blog posts

<ol>
{% for post in site.posts %}
<li>
    <span class="text-body-secondary">{{post.date | date: "%b %d"}}</span>
    -<a href="{{ post.url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ol>

The post variable contains title, URL and date for a blog post. It also contains author data & other front matter that you have. I didn’t display the author here as it is a personal blog and the name is same on every post.

Jekyll has this trick up its sleeve that allows us to know if this is the first or last iteration of the loop. We now use it to include the starting and ending of the ordered list into the loop itself. We are doing this now because once we split the blog posts by year we will have multiple ordered lists one for each year. We are preparing for that in advance.

{% for post in site.posts %}
    {% if forloop.first %}
        <ol>
    {% endif %}
    <li>
        <span class="text-body-secondary">{{post.date | date: "%b %d"}}</span>
        -<a href="{{ post.url }}">{{ post.title }}</a>
    </li>
    {% if forloop.last %}
        </ol>
    {% endif %}
{% endfor %}

Full code

And now we will add years into the mix and the code becomes a lot more complex. Here is the code and the explanation is given below.

{% for post in site.posts  %}

{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}

{% if forloop.first %}
<div id="{{this_year}}" class="btn btn-outline-primary" data-toggle="collapse" data-target="#list-{{this_year}}">{{this_year}}</div>
<br><br>
<ol class="collapse.show" id="list-{{this_year}}">
{% endif %}
<li>
    <span class="text-body-secondary">{{post.date | date: "%b %d"}}</span>
    - <a href="{{ post.url }}">{{ post.title }}</a>
</li>

{% if forloop.last %}
    </ol>
{% else %}
    {% if this_year != next_year %}
        </ol>
        <div id="{{next_year}}" class="btn btn-outline-primary" data-toggle="collapse" data-target="#list-{{next_year}}">{{next_year}}</div>
        <br><br>
        <ol class="collapse" id="list-{{next_year}}">
    {% endif %}
{% endif %}

{% endfor %}

Code Explanation

  1. In each iteration of the loop we first capture the year of the current post and the next post and save it.
  2. If this is the first iteration of the loop then we display the year and add an accordion. Now open an ordered list.
  3. Display post with link and date.
  4. If this is the last iteration of the loop close the ordered list.
  5. If not, Check if the next year is different from the current one. If the years change, close the current ordered list and open a new one with year and accordion.
  6. Continue the loop

Note: I couldn’t embedded the code within the website because Jekyll is parsing that despite being within a code block.