> ## Content Index
> Fetch the complete content index at: https://getpublii.com/dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Yearly archive for posts

- URL: https://getpublii.com/dev/yearly-archive-for-posts/
- Published: 2021-02-02T15:10:31.456Z
- Updated: 2021-02-02T15:29:43.674Z
- Description: See how to easily implement a yearly archive for your static website built with Publii Static Site CMS.
- Author: Tomasz Dziuda
- Tags: Custom Helpers

Publii does not contain archives by date, but it is possible to create a helper which will create such functionality. To implement such feature we need two simple custom helpers.

## Helpers source code

We need to built two helpers:

1.  first will be used to generate years
2.  second will retrieve posts from a specific year

Create the `helpers.js` file and put the following code in it (if you have the `helpers.js` file in your theme - please copy only the `yearsInArchive` and `getPostsByYear` functions from the below code):

```javascript
let themeHelpers = {
    yearsInArchive: function(startYear) {
        let years = [];
        let currentYear = new Date().getFullYear();
        for (let i = currentYear; i >= startYear; i--) {
          years.push(i);
        }
        return years;
    },
    getPostsByYear: function(posts, year) {
      return posts.filter(post => new Date(post.createdAt).getFullYear() === year);
    }
};
module.exports = themeHelpers;
```

The `yearsInArchive` helper returns every year from the given date. So for example for value **2016** it will return an array with the following values: **2021**, **2020**, **2019**, **2018**, **2017**, **2016**. You can reverse the order of years (if you want to use ascending order) by adding:

```javascript
years.reverse();
```

Directly before line:

```javascript
return years;
```

We will need this array to generate lists of posts grouped by years and using the creation date. If you need to group your posts by the last modification date - just replace `post.createdAt` with `post.modifiedAt`.

## How to create yearly archive

You need to create [post template](#INTERNAL_LINK#/post/83) and as its content please use the following code in place of the normal post content:

```javascript
<h2>Blog archive</h2>

<ol>
     {{#each (yearsInArchive 2016) }}
     <li>
            <h3>{{ this }}</h3>
            
            {{#if (getPostsByYear @website.contentStructure.posts this)}}
                <ol>
                     {{#each (getPostsByYear @website.contentStructure.posts this)}}
                     <li>{{title}} - {{date createdAt 'YYYY-MM-DDTHH:mm'}}</li>
                     {{/each}}
                </ol>
            {{else}}
                <strong>No posts</strong>
            {{/if}}
     </li>
     {{/each}}
</ol>
```

The above code requires some explanation:

-   In the <ol> element we generate archive using the yearsInArchive helper. Please notice, that we use Handlebars [subexpressions](https://handlebarsjs.com/guide/expressions.html#subexpressions)
-   To display the year, we are using the `{{ this }}` syntax - it will return years in the descending order.
-   To provide list of posts, we are using [@website.contentStructure.posts](#INTERNAL_LINK#/post/72) global variable - it contains all posts of your website. Please remember - the [contentStructure must be enabled](#INTERNAL_LINK#/post/19) in your theme.
-   Also we support a case when there are no posts in a specific year. Then the **No posts** text is displayed.

Variant which displays only years with posts (it skips years without posts):

```javascript
<h2>Blog archive</h2>

<ol>
     {{#each (yearsInArchive 2016) }}
     <li>
            {{#if (getPostsByYear @website.contentStructure.posts this)}}
            <h3>{{ this }}</h3>
            
            <ol>
                  {{#each (getPostsByYear @website.contentStructure.posts this)}}
                  <li>{{title}} - {{date createdAt 'YYYY-MM-DDTHH:mm'}}</li>
                  {{/each}}
            </ol>
            {{/if}}
     </li>
     {{/each}}
</ol>
```

In the above code we have removed **No posts** handling and we have moved year display inside condition which checks if some posts are available.

Please remember - you can use any [Post item](#INTERNAL_LINK#/post/85) elements inside the `#each` loop which uses the getPostsByYear helper.

## Summary

As you can see - creating yearly archive is not a complex task in Publii. It is also worth considering to create separate page for every year if you have a long list of posts. Then the additional loop with use of the `yearsInArchive` helper won't be required.
