Javascript Data Files
and you
Bryan Robinson
11ty Fan
Designer Who Codes
Host @ That's My Jamstack
DevRel @ Sanity.io
@brob
11ty Data Files
11ty Data Files
{
"siteName": "My amazing site",
"arrays": [
"Sure",
"why",
"not"
]
}
_data/settings.json
<h1>{{ settings.siteName }}</h1>
<ul>
{% for item in settings.arrays %}
<li>{{ item }}</li>
{% endfor %}
</ul>
_includes/index.njk
Me using static data file
Me using JS data file
11ty JS Data Files
11ty JS Data Files
module.exports = function() {
return [
"Pikachu",
"Bulbasaur",
"Charmander",
"only the original",
"151 because I'm old"
];
};
_data/pokemon.js
<h1>Pokemon</h1>
<ul>
{% for pokemon in pokemon %}
<li>{{ pokemon }}</li>
{% endfor %}
</ul>
_includes/index.njk
Fetch Data from an API
const fetch = require('node-fetch');
const fetchPokemon = () => {
const promises = [];
for (let i = 1; i <= 150; i++) {
const url = `https://pokeapi.co/api/v2/pokemon/${i}`;
promises.push(fetch(url).then((res) => res.json()));
}
return Promise.all(promises).then((results) => {
const pokemon = results.map((result) => ({
name: result.name,
image: result.sprites['front_default'],
type: result.types.map((type) => type.type.name).join(', '),
id: result.id
}));
return pokemon;
});
};
module.exports = async function() {
return await fetchPokemon();
}
Use our API Data in a loop
<div class="container">
<h1>Robinson's Pokedex</h1>
<ul id="pokedex">
{% for pokemon in pokemon %}
<li class="card">
<img class="card-image" src="{{ pokemon.image }}"/>
<h2 class="card-title">{{ pokemon.id }}. {{ pokemon.name }}</h2>
<p class="card-subtitle">Type: {{ pokemon.type }}</p>
</li>
{% endfor %}
</ul>
</div>
Build Pages with our data
---
pagination:
data: pokemon
size: 1
alias: entry
permalink: "different/{{ entry.name | slug }}/index.html"
---
<!DOCTYPE html>
<html lang="en">
<head>
<title>Robinson's PokeDex</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div class="container">
<h1>{{ entry.id }}. {{ entry.name }}</h1>
<img class="card-image" src="{{ entry.image }}"/>
<p class="card-subtitle">Type: {{ entry.type }}</p>
</div>
</body>
</html>
More Use cases
Pull Meetups from Meetup.com
var axios = require('axios');
module.exports = async function() {
let url = `https://api.meetup.com/${process.env.MEETUP_URL }/events?photo-host=public&page=20&sig_id=${process.env.MEETUP_KEY}`;
return axios.get(url)
.then(function (response) {
return response.data;
})
.catch(function(error) {
console.log(error);
});
}
Pull Meetups from Meetup.com
<ul>
{% for meetup in meetups %}
<li>
<a href="{{ meetup.link }}">{{ meetup.name }}</a>
</li>
{% endfor %}
</ul>
Pull Meetups from Meetup.com and filter
var axios = require('axios');
module.exports = async function() {
let url = `https://api.meetup.com/${process.env.MEETUP_URL }/events?photo-host=public&page=40&sig_id=${process.env.MEETUP_KEY}`;
let stringMatch = ""; // Match meetup name against a string if you need to filter
return axios.get(url)
.then(function (response) {
let data = response.data;
if (stringMatch.length > 0) {
data = data.filter(meetup => {
return meetup.name.includes(stringMatch);
});
}
return data;
})
.catch(function(error) {
console.log(error);
});
}
Pull Meetups from Meetup.com and filter
// /filters/lookup.js
module.exports = function(array, filterString) {
array = array.filter(item => {
return item.name.includes(filterString);
});
return array
}
// /.eleventy.js
config.addFilter("lookup", require("./filters/lookup.js"));
// index.njk
{% assign meetupSlice = meetups | lookup: "Jamstack Toronto" | slice: "1" %}
Posts from a CMS (Sanity, anyone?)
const BlocksToMarkdown = require('@sanity/block-content-to-markdown')
const groq = require('groq')
const client = require('../utils/sanityClient.js')
const serializers = require('../utils/serializers')
const hasToken = !!client.config().token
async function getPosts () {
// Learn more: https://www.sanity.io/docs/data-store/how-queries-work
const filter = groq`*[_type == "post" && defined(slug) && publishedAt < now()]`
const projection = groq`{
_id,
publishedAt,
title,
slug,
excerpt,
mainImage{
alt,
asset
},
body,
"authors": authors[].author->
}`
const order = `| order(publishedAt asc)`
const query = [filter, projection, order].join(' ')
const pages = await client.fetch(query).catch(err => console.error(err))
const preparePosts = pages.map(generatePost)
return preparePosts
}
module.exports = getPosts
_data/post.js
Posts from Sanity
---
layout: layouts/post
tags:
- myPosts
pagination:
alias: post
data: posts
size: 1
addAllPagesToCollections: true
permalink: posts/{{ post.slug.current | slug }}/index.html
---
Posts from Sanity
<article>
<h1>{{ post.title }}</h1>
{% if post.mainImage.asset %}
<img src="{% imageUrlFor post.mainImage.asset._ref, 400, 400 %}" alt="">
{% endif %}
<p>Written by {% for author in post.authors %}{{author.name}}{% endfor %}</p>
{{ post.body | markdownify | safe }}
</article>
11ty is awesome and so are you
If you have questions, I'm on Twitter @brob
11ty JS Data Files and You
By Bryan Robinson
11ty JS Data Files and You
- 516