ssg  

Blog Archives is very common in Wordpress. It is also available in Jekyll in many ways.

Blog Archives can be achieved without plugin. You can make your own custom archives, that is more suitable for your project.

This archive column come from my custom liquid archives script, not just another auto widget as usual at another platform.

  • Archives by Year

  • Archives by Month

  • Sidebar Archive Column

  • Navigation Menu: Using YAML Data.

You can modify it for your own.


Few alternatives.

Before you start. It is worth to have a peek in this official jekyll-archives-plugin written in ruby that works with github.

I started searching for a pluginless jekyll archives and found these amazing script.

Above script taught me how to use post.next inside the for iteration loop. I’m using his method, post.next to mark opening html tag of list it, and post.previous to mark the closing tag.

  {% assign postsByYear = site.posts | group_by_exp:"post", "post.date | date: '%Y'"  %}
  {% for year in postsByYear %}

  {% for post in site.posts %}
  ...
    {% unless post.next %}
    ...
      {% assign year = post.date | date: '%Y' %}
      {% assign n_year = post.next.date | date: '%Y' %}
    ...
    {% endunless %}
  ...
  {% endfor %}

Unless is conditional statement. ‘unless’ is a shorter way to say ‘if not’. The idea comes from Ruby. Liquid template mimics this behaviour.

I can see that these smart coder have a ruby influence in writing their script style. You can see how efficient their code, in just a few lines, and its done.


Group By Year

The issue is when I try to extend for my purpose, it becomes more and more complicated. So I decide to rewrite, with different logic.

Luckily, there is another better method, grouping by expression.

I takes a couple of loops, the group name (outer) , then the post items (inner).

  {% assign postsByYear = site.posts | group_by_exp:"post", "post.date | date: '%Y'"  %}
  {% for year in postsByYear %}
      <div class ="archive-year">
        <a href="{{ site.baseurl }}/pages/archives-y#{{ year.name }}">
        {{ year.name }}</a>
      </div>
  ...
    <ul class="archive-month">
      {% assign postsByMonth = year.items | group_by_exp:"post", "post.date | date: '%m'" %}
      ...
    </ul>
  ...
  {% endfor %}

Pay attention to to the group_by_exp:

  • name, and

  • items, as below


Group By Month

The inner loop is grouping by month. This takes a little bit of sorting.

    <ul class="archive-month">
      {% assign postsByMonth = year.items | group_by_exp:"post", "post.date | date: '%m'" %}
      {% assign postsByMonthSorted = postsByMonth | sort: 'name' | reverse %}

      {% for month in postsByMonthSorted %}
      <li class="list-month">
          ...
          <ul class="archive-item">
          {% for post in month.items %}
          <li class="list-content">    
            <a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
          </li>
          {% endfor %}
          </ul>
          ...
      </li>
      {% endfor %}
    </ul>

You can see the complete result in this archive page displayed by year and month. It is just an archive of posts sorted by date.


Let’s go further, archive page displayed by month. With the same logic, It won’t go that complicated.

I put the logic in _includes section, because I want to reuse the code.

And finally, let’s make it a sidebar as below figure.

It is a little bit longer, because I only show archives with the same month with the current post. So I have to make a comparison with current post.

    {% capture cache %}
    ...
      {% assign pg_year  = page.date | date: '%Y' %}
      {% assign pg_month = page.date | date: '%m' %}
    ...
    {% endcapture %}

Last, the header navigation bar drop down menu.

The YAML part

And the header part

    {% for link in site.data.navigation %}
    ...
      {% unless link.dropdown %}
      ...
      {% else %}
        {% for sublink in link.dropdown %}
        ...
        {% endfor %}
      {% endunless %}
    ...
    {% endfor %}

Sample screenshot here.

Jekyll Liquid Archives Without Plugin

Sample complete code here.

<div class="card">
  <div class="card-header bg-dark text-light">
    <p class="card-title float-left">Archives</p>
    <span class="fa fa-archive float-right"></span>
    <div class="clearfix"></div>
  </div>
  <div class="card-body">
  {% assign pg_year  = page.date | date: '%Y' %}
  {% assign pg_month = page.date | date: '%m' %}
  
  {% assign postsByYear = site.posts | group_by_exp:"post", "post.date | date: '%Y'"  %}
  {% for year in postsByYear %}
      <div class ="archive-year">
        <a href="{{ site.baseurl }}/pages/archives-y#{{ year.name }}">
        {{ year.name }}</a>
      </div>

    {% if pg_year == year.name %}
    <ul class="archive-month">
      {% assign postsByMonth = year.items | group_by_exp:"post", "post.date | date: '%m'" %}
      {% assign postsByMonthSorted = postsByMonth | sort: 'name' | reverse %}

      {% for month in postsByMonthSorted %}
      <li class="list-month">
        {% for post in month.items limit:1 %}
        <span class ="archive-month">
          <a href="{{ site.baseurl }}/pages/archives-m#{{ post.date | date: '%Y-%m' }}">
            {{ post.date | date: '%B %Y' }}
          </a></span>
        {% endfor %}

          {% if pg_month == month.name %}
          <ul class="archive-item">
          {% for post in month.items %}
          <li class="list-content">    
            <a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
          </li>
          {% endfor %}
          </ul>
          {% endif %}
      </li>
      {% endfor %}
    </ul>
    {% endif %}
  {% endfor %}
  </div>
</div> 

It is not very sophisticated. I hope that, this script is useful.

Thank you for reading.