Random post button
in Leicester
Last week I added a random post button to the blog index.
Here’s how it works.
First create a simple JSON file with post url, title, and maybe tags.1 This is the template for generating the JSON:
[
{% for post in site.posts %}
{
"title" : "{{ post.title | escape }}",
"tags" : "{{ post.tags | join: ', ' }}",
"url" : "{{ post.url | prepend: site.baseurl }}"
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]
You’ve got to add ‘layout: null’ at the top of the file to stop jekyll from messing with the layout.
Otherwise the JSON is nothing complicated, just a big collection of titles, tags, and links. At the moment with 316 posts it comes out as a 43.7kB file, or 7.8kB when compressed for transfer.
And here’s the javascript file:
async function postrandomiser(){
const response = await fetch('post_list.json');
const names = await response.json();
const random = Math.floor(Math.random() * names.length);
var randompost = names[random];
location.href = randompost["url"];
};
document.getElementById('random-post-button').onclick = function(){
postrandomiser();
}
Then just a button element to call the postrandomiser function.2
<button id="random-post-button">Random post</button>
Finally, some graceful degradation for people who don’t have Javascript enabled, a link wrapped inside a noscript tag.
<noscript>
{% assign randompost = site.posts | sample: 1 %}
<a href="{{ randompost.url | prepend: site.baseurl }}">Random post</a>
</noscript>
The ‘sample’ filter randomises the list of posts, and every time the site is generated you get another random url. It’s not as useful as a button which gives a random post with every page load, but good enough as an alternative.
-
No ‘onclick’ event added to the button itself. No inline scripts. ↩