Preface
Goal: Using static data feature.
Source Code
This article use tutor-07 theme. We will create it step by step.
8: Friends
As every SSG does, eleventy
also has feature to access static data.
Data: friends.json
I always like to give a link to my fellow blogger folks. So I made a special data for these great people.
[
{
"title": "Nanda 'Yunee' Okitavera",
"url": "https://okitavera.me/"
},
{
"title": "BanditHijo (R)-Chive",
"url": "http://bandithijo.com/"
},
{
"title": "Elianiva",
"url": "https://elianiva.github.io/"
},
{
"title": "Sira Argia (Aflasio)",
"url": "https://aflasio.netlify.app/"
},
...
]
Filter: Shuffle
I need to show five bloggers randomly for each pages.
We already have limit
filter in previous article.
Now we require to add a new shuffle
filter in main configuration.
Since nunjucks does not have a built in function for shuffle.
We need to add shuffle
filter in .eleventy.js
:
// Random Filter: With the help from google search engine
eleventyConfig.addNunjucksFilter("shuffle", function(array) {
return helper.shuffle(array);
});
// Limit Filter: Copy paste from Jérôme Coupé
eleventyConfig.addNunjucksFilter("limit", function(array, limit) {
return array.slice(0, limit);
});
After duckduckwent fo a while, I got this shuffle code from stackoverflow:
Where the code in helper.js
file is as below:
exports.shuffle = function(array) {
var currentIndex = array.length;
var temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
};
Later you can use this filter as code below:
{% set links = friends | shuffle | limit(5) %}
Again, you can see how flexible nunjucks is.
Partial Widget: Nunjucks Friends
{% extends "layouts/widget.njk" %}
{% set color = 'pink' %}
{% block widget_header %}
<strong>Isle of Friends</strong>
<span class="fas fa-child is-pulled-right"></span>
{% endblock %}
{% block widget_body %}
{% set links = friends | shuffle | limit(5) %}
<ul class="widget-list">
{%- for friend in links -%}
<li><a href="{{ friend.url }}"
>{{ friend.title }}</a></li>
{%- endfor -%}
</ul>
{% endblock %}
Render: Browser
You can open page
kind, or post
kind, to test this widget
.
9: Backlink: External Archive
I have four blogs, each already have generated archive data. So it makes sense that I put backlinks from my own static blog, in each post.
Data: archive-github.json
My generated data from my Jekyll site looks like below:
{
"system-2020-02-02-presentation-linux-diversity-html": {
"title": "Presentation - Learning Linux Diversity",
"url": "/system/2020/02/02/presentation-linux-diversity.html"
},
"desktop-2020-01-20-presentation-desktop-customization-html": {
"title": "Presentation - Desktop Customization",
"url": "/desktop/2020/01/20/presentation-desktop-customization.html"
},
"desktop-2019-12-03-awesome-presentation-statusbar-html": {
"title": "Awesome WM - Presentation - Statusbar",
"url": "/desktop/2019/12/03/awesome-presentation-statusbar.html"
},
...
}
I put this in my eleventy static data directory manually.
Data: archive-gitlab.json
And, my generated data from my Hugo site looks like below:
{
"/frontend/2020/05/15/template-koa/": {
"title": "Template - Koa",
"content": "Templating Engine Configuration in KoaJS.",
"url": "/frontend/2020/05/15/template-koa/",
"author": "epsi",
"category": "frontend"
},
"/frontend/2020/05/13/template-express-handlebars/": {
"title": "Template - Express - Handlebars",
"content": "Feeding Data in ExpressJS, and Process in a Loop with Handlebars.",
"url": "/frontend/2020/05/13/template-express-handlebars/",
"author": "epsi",
"category": "frontend"
},
...
}
I also put this in my eleventy static data directory manually.
Filter: Value
I do not want to make different archive for each target sites. My Jekyll data archive should be the same for all reader. And my Hugo data archive also should be the same for all reader.
For this to be happened,
I need to add new value
filter in main configuration.
Since nunjucks does not have a built in function for value.
We need to add value
filter in .eleventy.js
:
// values Filter: With the help of w3schools
eleventyConfig.addNunjucksFilter("values", function(array) {
return Object.values(array);
});
Later you can use this filter as code below:
{% set archives = archives_github | values %}
Partial Widget: Nunjucks Archive Github
{% extends "layouts/widget.njk" %}
{% set color = 'orange' %}
{% block widget_header %}
<strong>Linux/BSD Desktop Customization</strong>
<span class="fas fa-fingerprint is-pulled-right"></span>
{% endblock %}
{% block widget_body %}
{% set archives = archives_github | values %}
{% set posts = archives | shuffle | limit(5) %}
<ul class="widget-list">
{%- for post in posts -%}
<li><a href="http://epsi-rns.github.io{{ post.url }}"
>{{ post.title }}</a></li>
{%- endfor -%}
</ul>
{% endblock %}
Render: Browser
You can open page
kind, or post
kind, to test this widget
.
Partial Widget: Nunjucks Archive Gitlab
{% extends "layouts/widget.njk" %}
{% set color = 'pink' %}
{% block widget_header %}
<strong>Web/Mobile Development</strong>
<span class="fas fa-fingerprint is-pulled-right"></span>
{% endblock %}
{% block widget_body %}
{% set archives = archives_gitlab | values %}
{% set posts = archives | shuffle | limit(5) %}
<ul class="widget-list">
{%- for post in posts -%}
<li><a href="http://epsi-rns.gitlab.io{{ post.url }}"
>{{ post.title }}</a></li>
{%- endfor -%}
</ul>
{% endblock %}
Render: Browser
You can open page
kind, or post
kind, to test this widget
.
10: Related Posts
We have already seen in previous article, that we can generate our own custom data:
Data: archives.json
Using previously saved file _data/archives.json
.
Note that this archive saved manually from generated content.
{
"15032535": {
"title": "Deftones - Be Quiet and Drive",
"url": "/lyrics/deftones-be-quiet-and-drive/"
},
"18091335": {
"title": "Disturbed - Stupify",
"url": "/lyrics/disturbed-stupify/"
},
"15071535": {
"title": "Marilyn Manson - Sweet Dreams",
"url": "/lyrics/eurythmics-sweet-dreams/"
},
"18011535": {
"title": "House of Pain - Jump Around",
"url": "/lyrics/house-of-pain-jump-around/"
},
"15072535": {
"title": "Marilyn Manson - Redeemer",
"url": "/lyrics/marylin-manson-redeemer/"
},
...
}
The ID, comes from dates and minutes. automatic generated by script from previous article.
Page Content: Frontmatter
Now we can add variable in page content.
Consider name the variable related_link_ids
.
This should contain array of id
in yaml.
---
layout : post
title : Marilyn Manson - Redeemer
date : 2015-07-25 07:35:05
tags : ["industrial metal", "90s"]
related_link_ids :
- 15071535 # Sweet Dreams
---
...
---
layout : post
title : Marilyn Manson - Sweet Dreams
date : 2015-07-15 07:35:05
tags : ["industrial metal", "90s"]
related_link_ids :
- 15072535 # Redeemer
---
...
Filter: Value
Unlike previous widget that need values
filter.
This widget require keys
filter.
// values Filter: MDN web docs
eleventyConfig.addNunjucksFilter("keys", function(array) {
return Object.keys(array);
});
Later you can use this filter as code below:
{% set ids = archives | keys %}
Layout: Nunjucks Page or Post
Consider examine only related-posts.
The widget should only be shown, if ids
set in frontmatter.
<aside class="column is-one-thirds">
{%- if related_link_ids -%}
{% include "widget/related-posts.njk" %}
{%- endif -%}
</aside>
Notice that, the widget won’t be shown,
if there is no ids
set in frontmatter.
Partial Widget: Nunjucks Related Posts
{% extends "layouts/widget.njk" %}
{% set color = 'lime' %}
{% block widget_header %}
<strong>Related Posts</strong>
<span class="fa fa-link is-pulled-right"></span>
{% endblock %}
{% block widget_body %}
<ul class="widget-list">
{%- for link_id in related_link_ids -%}
<li>
{% set ids = archives | keys %}
{%- for id in ids -%}
{%- if link_id == id -%}
<a href="{{ archives[id].url | url }}"
>{{ archives[id].title }}</a>
{%- endif -%}
{%- endfor -%}
</li>
{{ end }}
{%- endfor -%}
</ul>
{% endblock %}
I know it is a little bit complex.
And lately, I rarely use this related_link_ids
feature myself.
But I still keep this feature for a few of my posts.
Render: Browser
You can open post
kind, to test this widget
.
11: Summary
Layout: Post
As a summary here is the post
layout.
{% extends "layouts/columns-double.njk" %}
{% block main_color %}{{ color or 'blue' }}{% endblock %}
{% block blog_header %}
{% include "post/blog-header.njk" %}
{% endblock %}
{% block aside %}
<aside class="column is-one-thirds">
{%- if related_link_ids -%}
{% include "widget/related-posts.njk" %}
{%- endif -%}
{% include "widget/archive-grouped.njk" %}
{% include "widget/tags.njk" %}
</aside>
{% endblock %}
{% block aside_widget_all %}
<aside class="column is-one-thirds">
{% include "widget/tags.njk" %}
{% include "widget/archive-grouped.njk" %}
{% include "widget/recent-posts.njk" %}
{%- if related_link_ids -%}
{% include "widget/related-posts.njk" %}
{%- endif -%}
{% include "widget/friends.njk" %}
{% include "widget/archive-gitlab.njk" %}
{% include "widget/archive-github.njk" %}
{% include "widget/oto-spies.njk" %}
{% include "widget/affiliates.njk" %}
</aside>
{% endblock %}
You can add or remove widget, as you want them to be.
Render: Browser
The looks in desktop screen is shown as below figure:
What is Next ?
Consider continue reading [ Eleventy - Pagination - Intro ]. We are going to move on to complex component called pagination.
Thank you for reading.