Many readers want to browse old posts or find posts that they read but don't have the the link for anymore. Even though blogging favors "today", some older posts still offer value over longer periods of time and the best way to make such posts available is through an archives page. In this post I’ll explain how you can create an archive page for your Ghost Theme.

Some of the advantages of an archive page:

  • it can increase engagement and maintain a positive community around your content
  • it can boost the amount of time that people spend on your site
  • you can increase the number of page views on each article
  • more chances to convert visitors into subscribers and/or customers.

So let's start creating a archive.

The simple archive page

Create a new file in the root folder of your theme, call it page-archive.hbs, it's a good idea to start from your page.hbs file. What we need to start with is fetching the posts and that is very easy to do using the {{get}} and {{foreach}} helpers.

{{#get "posts" limit="all" order="published_at desc"}}
  <article class="content-wrap">
    {{#foreach posts visibility="all"}}
      <a href="{{url}}" class="archive-post">
        <time datetime="{{date published_at format="YYYY-MM-DD"}}" class="archive-post__date">
          {{date published_at format="DD MMM YYYY"}}
        </time>
        <h2 class="archive-post__title">{{title}}</h2>
      </a>
    {{/foreach}}
  </article>
{{/get}}

Let's break it down, the first part is fetching the posts, limit="all" tells the API we need all the posts (if you do not specify a limit the default is from your package.json config.posts_per_page). We will put all posts within an article element, then loop through all the fetched posts using the {{foreach}} helper. The visibility="all" will make sure all posts are listed regardless if they are public, free or member posts. The next part is the layout of the archive posts, in this case a simple one, listing the date and title.

After you have uploaded your modified theme (or restarted your Ghost instance) and navigate to yoursite.com/archive you should see the list of posts.

While this works fine, if you have a lot of posts it might not be a good idea to fetch them all (especially if you want to display the image as well). So let's take a look at another approach.

The more advanced archive

In this case we will create a new file called archive.hbs in the root folder of the theme, then the next step is to add a few lines to our routes.yaml file. By default you should have the collections and taxonomies defined and now we will add a new section under the routes:

routes:
  /archive/:
    controller: channel
    template: archive

collections:
  /:
    permalink: /{slug}/
    template: index
  
taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

In the end the routes.yaml should look like above (of course depending on your site this could be different as you might have another setup). Upload the modified file through Ghost Admin > Labs clicking on Upload routes.yaml.

Now let's start modifying the archive.hbs file:

{{!< default}}

{{!-- Archive Page --}}
<div class="container wrapper">
  <h1 class="archive__title">{{t "Archive"}}</h1>
  <div class="archive__excerpt">
    {{#get "posts"}}
      {{t "Browse the complete archive of {total} posts." total=pagination.total}}
    {{/get}}
  </div>
  
  <div class="content">
    <div class="archive js-post-feed">
      {{#foreach posts visibility="all"}}
        <div class="archive-post-wrap post-year-{{date format="Y"}} js-post-card"> 
          <div class="archive-post-label m-t m-b-sm fw-600">{{date format="YYYY"}}</div>
          <article class="archive-post">
            <time datetime="{{date published_at format="YYYY-MM-DD"}}"
              class="text-acc-3">{{date published_at format="DD MMM YYYY"}}
            </time>

            <h2 class="archive-post__title fw-500 m-0 text-acc-2">
              <a class="archive-post__link flex-1" href="{{url}}">{{title}}</a>
            </h2>
          </article>
        </div>
      {{/foreach}}
    </div>

    {{!-- Pagination --}}
    {{pagination}}
  </div>
</div>

First part of the code is the page title and then a small excerpt listing the number of posts in total using the pagination.total in the {{get "posts"}} context.

Next we have the posts, and note that in since we added the /archive/ to the routes and having the controller channel we don't need to fetch the posts using the {{get}} helper, as they will be available by default (paginated).

Within the {{foreach}} we have the layout of the post, which in this case has a post date and title, also some additional elements like the .archive-post-wrap and the .archive-post-label, these elements will be used to achieve grouping of posts by the year they were posted in.

Last part is the {{pagination}}, since we have a paginated content we have to offer the users the possibility to navigate though the pages of content. And the pagination helper will be the control for that.

For the grouping you can use css to not display the labels(beside the first one) until it's a different year, check out this thread on the forum for more details.

Final result

The second approach is part of Dashi Ghost Theme with a load more posts button instead of pagination.

Here is how it looks: Tag Dropdown

You can see it live on the Dashi Demo. I hope this was helpful.