Let's Learn 11ty Part 4: Data in Eleventy
Tags: tutorial, ssg, eleventy, webdev
Published: 2022-06-07 13:23:30

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:
```html
 {% 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:
```html
 ---
 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:
```md
 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0e6332s7mgxf415j9sm.png)
> 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:

```md
 # 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`

```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

```json
 {
   "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 

```html
<title>{{site.title}}{% 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:

```html
<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

```md
 ---
 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

```json
 {
   "layout": "blogLayout",
   "tags": "post"
 }
```
With this done, we can remove the layout and tags from our post files so they now look like this:

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

![with data direcory file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jq5hjo26qaonuad72yta.png)

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**:
- The working repo: https://github.com/Psypher1/learneleventy
- The docs: https://www.11ty.dev/docs/
- The discord: https://www.11ty.dev/blog/discord/


---

###  Thank you for reading, let's connect!
Thank you for visiting this little corner of mine. Let's connect on [**Twitter**](https://twitter.com/Psypher1), [**Polywork**](https://www.polywork.com/psypher1) and [**LinkedIn**](https://www.linkedin.com/in/jamesmidzi/)