Eleventy
Build a Static Site with Backend Data Handling
.eleventy.js
// AZUL CODING ---------------------------------------
// Eleventy - Build a Static Site with Backend Data Handling
// https://youtu.be/71q-C9BVUng
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksFilter("trimText", function(text) {
if (text.length >= 40)
return text.substring(0, 40) + "...";
else
return text;
});
eleventyConfig.addNunjucksFilter("filterComments", function(comments, postID) {
return comments.filter(x => x.postId == postID);
});
eleventyConfig.addNunjucksFilter("exclude", function(posts, excluded) {
return posts.filter(x => excluded.indexOf(x.id) == -1);
});
return {
dir: {
input: "src",
output: "_site",
},
};
};
index.njk
---
title: "Posts - Azul Coding"
layout: "base.njk"
---
<!-- AZUL CODING --------------------------------------- -->
<!-- Eleventy - Build a Static Site with Backend Data Handling -->
<!-- https://youtu.be/71q-C9BVUng -->
{% for post in posts | exclude(excluded) %}
<a class="card" href="/post/{{ post.id }}">
<div class="content">
<div class="text-overlay">
<h2>Post {{ post.id }}</h2>
<p>{{ post.title | trimText }}</p>
</div>
</div>
</a>
{% endfor %}
post.njk
---
title: "Post - Azul Coding"
pagination:
data: posts
size: 1
alias: post
permalink: "post/{{ post.id }}/"
layout: "base.njk"
---
<!-- AZUL CODING --------------------------------------- -->
<!-- Eleventy - Build a Static Site with Backend Data Handling -->
<!-- https://youtu.be/71q-C9BVUng -->
<div class="post-container">
<h2>Post {{ post.id }}</h2>
<p>{{ post.title }}</p>
<p>{{ post.body }}</p>
<p><a href="/">Go back</a></p>
<h3>Comments</h3>
<ul>
{% for comment in comments | filterComments(post.id) %}
<li>
<p>{{ comment.body }}</p>
</li>
{% endfor %}
</ul>
</div>
base.njk
<!-- AZUL CODING --------------------------------------- -->
<!-- Eleventy - Build a Static Site with Backend Data Handling -->
<!-- https://youtu.be/71q-C9BVUng -->
<!DOCTYPE html>
<html lang="en-GB">
<head>
<title>{{ title }}</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body {
margin: 40px;
background-color: #004961;
display: flex;
flex-wrap: wrap;
gap: 25px;
}
* {
font-family: 'Inter', sans-serif;
color: white;
}
h2 {
margin: 15px 0 5px 20px;
}
p {
font-size: 16px;
margin: 0 20px 20px 20px;
}
.card {
width: 250px;
height: 250px;
background-color: #1576C1;
border-radius: 15px;
box-shadow: 0 0 10px rgb(0, 0, 0, 0.4);
display: flex;
text-decoration: none;
transition: background-color 0.3s;
}
.card:hover {
background-color: #2697EF;
}
.content {
height: 100%;
width: 100%;
border-radius: 15px;
display: flex;
}
.text-overlay {
margin-top: auto;
width: 100%;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
background-color: rgb(0, 0, 0, 0.3);
}
.post-container h3 {
margin: 80px 0px 5px 20px;
}
</style>
</head>
<body>
{{ content | safe }}
</body>
</html>
data.js
// AZUL CODING ---------------------------------------
// Eleventy - Build a Static Site with Backend Data Handling
// https://youtu.be/71q-C9BVUng
const Cache = require("@11ty/eleventy-cache-assets");
module.exports = async function() {
try {
// Change this link to whatever you want, but bear in mind that
// the name of this file is its access key in the templates
// e.g. the JSON returned in data.js would be accessed as {{ data }}
return await Cache("https://jsonplaceholder.typicode.com/posts", {
duration: "1d", // cached for one day
type: "json"
});
} catch(e) {
return {
error: "An error occurred."
};
}
};