Let’s Learn 11ty Part 4: Data in Eleventy

Last time we did quite a bit of work on our site to make it come together. At this point, I think it’s time we talk about Data in Eleventy.

But first, let’s improve the flow on our blog posts by adding next and previous post links to the bottom of our posts.

Adding Next/Previous Post Links

Let’s start by adding a third post in our blog folder.
Now we are going to implement what is called layout chaining in Eleventy.

We will start by creating a partial for our pagination. Yes, this is pagination (I have an article planned for this concept, but later).

In _includes/partials create a paginate.njk and place this in it:

 {% set previousPost = collections.post | getPreviousCollectionItem(page) %}
 {% set nextPost = collections.post | getNextCollectionItem(page) %}
 {% if previousPost %}Previous: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a>{% endif %}
 <br>
 {% if nextPost %}Next: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a>{% endif %}

In the snippet above, we introduce a new feature of Eleventy – set . Set is used when we want to create a specialised piece of content that is not present in our site.

  • We create a previousPost and nextPost that relates to our post collection
  • Then we make an if statement to check if these exist in our collection.
    • If they do, output the URL of that post otherwise display nothing.

Then in _layouts make a new file called blogLayout.njk and place this in it:

 ---
 layout: base
 ---
 {{content| safe}}
 <br/>
 {% include "partials/_paginate.njk" %}
 <br>
 <hr>
 <a href="/blog">Blog Home</a>

Next, we change the layout key in the frontmatter of our post files to this:

 title: First Post
 layout: blogLayout # modify this line
 tags: post

We are switching the layout we use for posts to the one we just made – this is where we’ve chained layouts. A post uses the blogLayout which uses the base layout.

Previous and Next Post
I’ve added more styles to make the page look better

Permalinks

Permalinks are another feature of Eleventy(that I forgot 😁) that allows you to determine what a pages’ URL becomes

Say for example you chose to place your page files in a pages directory, but didn’t want them to be output as [your_site_url]/pages/about_page but as [your_site_url]/about_page, this is where permalinks come in:

 # src/pages/about.md
 ---
 layout: base
 title: About
 tags: page
 permalink: /about/
 ---

Eleventy Data Cascade

Eleventy’a data cascade refers to the order in which Eleventy renders site data.

The closer (more specific) data is to content, the higher priority it has

That cascade, in order of priority is:

  1. Computed Data – data derived from other data
  2. Frontmatter Template Data – in a single template
  3. Template Data Files – Applied to one file
  4. Layout Frontmatter Data – Applied to all templates that use that layout.
  5. Directory Data Files
  6. Configuration Global Data
  7. Global Data Files

When we make use of this data, it is usually in reverse order, with global data first, then config data and so on…

When I say template, it just means any file with content

Currently we have used two type two kinds of Eleventy data

  • Layout Template Data – when we rendered the navigation and post list
  • Front Matter Data – the title frontmatter in our pages

Let’s make use of some of the other types of data

Global Data Files

If you recall when we set up our project, we did this in our .eleventy.js

  return {
     dir: {
       input: "src",
       data: "_data",  //take note of this
       includes: "_includes",
       layouts: "_layouts",
     },
   };

Global data refers to files we place in the _data folder. In most instances we use global data for things we want site wide, for example the site title and description.

Let’s make a global data file to house some of our site data.

Make an _data folder in src and in in a site.json and place this in it

 {
   "title": "James Midzi",
   "description": "A site to showcase Eleventy features by building a site.",
   "keywords": "eleventy, 11ty, css, ssg"
 }

This will give us some global configuration options that will be used on the site.

Now, we will modify the head tag in base.njk to

<title>{{site.name}}{% if title %} - {{title}} {% endif %} </title>
    <meta name="description" content="
      {% if description %}
        {{description}}
      {% else %}
        {{site.description}}
      {% endif %}
    "/>

Above, we are running checks to see if the title and description data exists in our pages (templates), if it does render it. Otherwise, use the data in site.json (global data)

The final head tag should look like this:

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- stylesheet -->
   <!-- <link rel="stylesheet" href="{{ '/assets/css/style.css' | url }}"> -->
   <link rel="stylesheet" href="{{ '/assets/css/tailwind.css' | url }}">

   <!-- Meta -->
    <title>{{site.name}}{% if title %} - {{title}} {% endif %} </title>
    <meta name="description" content="
      {% if description %}
        {{description}}
      {% else %}
        {{site.description}}
      {% endif %}
    "/>
  </head>

NOTE: our data files can be json or javascript

The changes we have made will help with our site SEO

Config Global Data

I at present do not know the correct way to apply global config data. I will continue researching and asking questions. I will revisit this part when I have a better understanding of this.

Directory Data Files

These set data on a folder level, and they must be named the same as the folder they are in.

They apply data in it to everything contained in that folder.

Let’s take a look at our posts. We are currently setting this in each post’s frontmatter

 ---
 title: First Post
 layout: blogLayout
 tags: post
 ---

While this might be fine now, imagine if we added more posts. We would have to copy this frontmatter pattern into each of them.

A Data Directory File helps us with this repetition problem. Let’s do that, shall we?

In the src/blog folder, create a blog.json file and place this in it

 {
   "layout": "blogLayout",
   "tags": "post"
 }

With this done, we can remove the layout and tags from our post files so they now look like this:

---
title: First Post
description: This is my first post
---

with data direcory file

Checking our site, we can see that everything is still working. Now, if we add more posts, we only have to be concerned with the title and description.

Template Data Files

This data is applied on a file(template level) where if you had a about.md you can have data that applies only to it in a about.11tydata.js or about.11tydata.json

Computed Data

For the life of me, I can’t figure out how one would go about using computed data. But I believe someone in the Discord will be able to help. As with Config Data, I will return.

An Intermission

That was a lot right? Yeah, I know. But at least we have now covered some of the more involved parts of Eleventy and how you can make them work for you.

Conclusion

This has been one of the more longer tutorials of this series. I hope you all stayed till the end because understanding how data works will greatly improve how you build your Elevnety site.

In this article we:

  • Added pagination to our posts
  • Added a data file to manage site metadata (we will build on it later)
  • Added a directory data file to simplify the creation of new posts.
  • Talked about the data cascade in Eleventy.

As always:

Thank you for reading, let’s connect!

Thank you for visiting this little corner of mine. Let’s connect on Twitter, Polywork and LinkedIn