Title: Customizing Pelican archives page
Slug: customizing-pelican-archives-page
Date: 2017-01-28 11:00:00
Author: Kartones
Lang: en
Tags: Development, Python
og_image: https://images.kartones.net/posts/kartonesblog/new_archives_format.jpg
Description: How to customize the archives page of a blog using the Pelican platform, specifically grouping posts by year using Jinja template system.

I wanted to personalize the blog [archives page](https://blog.kartones.net/archives.html), as it was serving its purpose but was a bit messy:

![Old archives page](https://images.kartones.net/posts/kartonesblog/old_archives_format.jpg)

What I wanted was to visually differentiate posts grouping by year.

Checking the theme's article.html code, it was a simple loop without any customization option:
```
<ul>
{% for article in dates %}
    <li><a href="/{{ article.url }}">{{ article.title }}</a> {{ article.locale_date }}</li>
{% endfor %}
</ul>
```

As the template system uses Jinja, I tried using `set` to create variables on template-render time:
```
<ul>
{% set year = '1970' %}
{% for article in dates %}
    {% if not article.locale_date.startswith(year) %}
        {% set year = article.locale_date[:4] %}
        <li>{{ article.locale_date[:4] }}</li>
    {% endif %}
    <li><a href="/{{ article.url }}">{{ article.title }}</a> {{ article.locale_date }}</li>
{% endfor %}
</ul>
```

But it backfired on me as it was not working as expected: each article had the date repeated. Why? Because I later found that Jinja variables are only available at the scope they are created, not at inner ones, so I was actually creating two `year` variables, one outside of the loop (always with value `1970`) and another inside always set to `article.locale_date[:4]`.

How then to proceed then to detect different years? The answer was simple: use an old but always resourceful index-based `for` loop:
```
<ul>
{% for index in range(dates|length) %}
    {% set article = dates[index] %}
    {% if index == 0 %}
        <li>{{ article.locale_date[:4] }}</li>
    {% else %}
        {% set previous_article = dates[index-1] %}
        {% if not article.locale_date.startswith(previous_article.locale_date[:4])  %}
            <li>{{ article.locale_date[:4] }}</li>
        {% endif %}
    {% endif %}
    <li><a href="/{{ article.url }}">{{ article.title }}</a> {{ article.locale_date }}</li>
{% endfor %}
</ul>
```

Now I finally can play with the articles and check their dates and detect when the year changes. And while I could avoid the article variables, being used at build time I prefer legible code. Here are the final results:

![New format](https://images.kartones.net/posts/kartonesblog/new_archives_format.jpg)
