New site part 3 - individual posts

Part of a series about setting up the new 11ty version of this site

I'm going to do some (slightly) clever things with my collection of posts later, but first I need to work out how I'm going to write an individual page.

Collecting posts

I'll organise individual posts within my src/posts/ folder by year and month, but I want the permalink for each to only be based on the title of the post. I also want there to be "next post" / "last post" links for each individual post, so I need a unique layout.

So first thing to do is add a file posts.11tydata.js in my src/posts/ folder, which means I can set common front matter for all my posts:

// src/posts/posts.11tydata.js

module.exports = {
    permalink: "/{{ title | slugify }}/index.html",
    layout: "layouts/posts.njk",
    tags: ["post"]
}

This gives me a permalink based on the slug of the post's title, uses a new posts.njk layout (that we'll need to write), and makes a new 11ty collection called post.

Config

I want to make sure that my posts are sorted in reverse chronological order (most recent post first) which means defining the collection:

// eleventy.js - inside module.exports

module.exports = function(eleventyConfig) {

    ...

    // reverse the order of post collection
    eleventyConfig.addCollection('post', (collection) => {
        return collection.getFilteredByTag("post").reverse();
    });

    ...
}

Laying it out

  1. First we need, for 'this' post, to find out what the previous and next posts are.
// src/_includes/layouts/posts.njk - pt 1

---
layout: layouts/base.njk
---

{% set nextPost = collections.post | getNextCollectionItem %}
{% set previousPost = collections.post | getPreviousCollectionItem %}
  1. Some boilerplate layout, plus the post title (class names hopefully self-evident). This includes the content of the post, and the opening of the 'next/previous' element.
// src/_includes/layouts/posts.njk - pt 2

<div class="container">
    <div class="row">
        <div id="main-content-grid">
            <div id="main-content">

                <div class="post-title-header">
                    <h1 class="post-title as-h2">{{ title }}</h1>
                </div>
                
                <p class="post-date">
                    Posted on <span class="date">{{ date | postDate }}</span>
                </p>
                
                {{ content | safe }}

                <div class="next-previous">
  1. The 'next post' link. We have to use the previous post (because we've reversed the order), and I'm testing to make sure that there is a previous post. I've removed indent for easier reading
// src/_includes/layouts/posts.njk - pt 3
                
    {% if nextPost %}
    <p>Previous <a href="{{nextPost.url}}">{{nextPost.data.title}}</a></p>
    {% else %}
    <div></div>
    {% endif %}
  1. And the 'previous post' link. Unsurprisingly we need to use the next post in the collection.
// src/_includes/layouts/posts.njk - pt 4

    {% if previousPost %}
    <p class="right">Next <a href="{{previousPost.url}}">{{previousPost.data.title}}</a></p>
    {% else %}
    <div></div>
    {% endif %}
  1. And finally, wrap up the boilerplate.
// src/_includes/layouts/posts.njk - pt 5

                </div><!-- close the next-previous element>

            </div><!-- close the main-content element>
        </div><!-- close the main-content-grid element>
    </div><!-- close the row element>
</div><!-- close the container element>

Writing a post

My posts will be written in markdown; although I'll keep a year and month folder system to help organise them, the year, month and indeed filename aren't actually important — the permalink I set out above doesn't use any of them.

I've decided that I'll have some standard front matter in each file — a title (which I need, since it's used to generate the unique permalink), a date (used to sort the post collection) and some kind of content tagging that I'm choosing to call categories.

// example front matter for a post

---
title: Technical Sophistication
date: "2016-10-04"
categories: 
  - thoughts
---

// content here in markdown