Tristan Perry

Some Handy Jekyll Snippets

Many websites I visit nowadays seem quite bloated. Fairly plain websites whose pages carry out 200+ HTTP requests, pages with 1 MB+ of Javascript to download before they can render a simple website etc. Hence I’ve found Jekyll to be a really useful tool in generating simple, static HTML websites - but with the power of blog platforms (with posts and pages) in the backend.

Whilst the Jekyll docs are great, there’s been a few things that I’ve wanted to do with Jekyll which weren’t obvious - hence this post which I’ll use to document (or link to) any useful Jekyll snippets I’ve found.

Table of Contents

Show the 10 most recent posts

This is straightforward enough, and utilises the limit literal to show the top 10 posts sitewide:

<ul id="recent-articles">
    {% for post in site.posts limit:10 %}
        <li>
        {{ post.date | date: "%d %b %Y" }}:
        <a class="post-link" href="{{ post.url | relative_url }}" title="{{ post.description }}">{{ post.title | escape }}</a>
        </li>
    {% endfor %}
</ul> 

Or the last 10 posts within a specific category:

<ul id="recent-articles">
    {% for post in site.categories["my-category"] limit:10 %}
        <li>
        {{ post.date | date: "%d %b %Y" }}:
        <a class="post-link" href="{{ post.url | relative_url }}" title="{{ post.description }}">{{ post.title | escape }}</a>
        </li>
    {% endfor %}
</ul> 

See the final heading for a way of showing the last 10 posts within multiple (but not all) of your site’s categories.

Show all posts from the current month

It can be quite handy to show just the posts from the current month - for example a news section which shows recent posts:

<ul id="category-articles">
    {% for post in site.categories["news"] %}
        {% assign postmonth = post.date | date: "%B %Y" %}
        {% assign currentmonth = site.time | date: "%B %Y" %}
        {% if postmonth == currentmonth %}
            <li>
                <a class="post-link" href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
                <p class="post-datetime">{{ post.date | date_to_long_string }}</p>
                <p class="post-description">{{ post.description }} {{date}}</p>
            </li>
        {% endif %}
    {% endfor %}
</ul>

Show all posts from the past 3 weeks

It can be useful to show all posts within N weeks (or days, or months etc etc). Whilst Jekyll is obviously a static-site generator (so the end HTML won’t magically update itself on your server!), if you use the following on a regularly-published page on your website, it’ll work well:

<ul id="category-articles">
    {% assign max_seconds = 1814000 %}
    {% for post in site.categories["news"] %}
        {% assign post_timestamp = post.date | date: "%s" | plus: 0 %}
        {% assign cut_off_timestamp = "now" | date: "%s" | minus: max_seconds  %}
        {% if post_timestamp > cut_off_timestamp %}
            <li>
                <a class="post-link" href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
                <p class="post-datetime">{{ post.date | date_to_long_string }}</p>
                <p class="post-description">{{ post.description }} {{date}}</p>
            </li>
        {% endif %}
    {% endfor %}
</ul>

sitemap.xml file for SEO/search engine bots

It’s always handy to have a sitemap.xml file, linked to from your robots.txt file. Firstly, this can be submitted to Google’s Webmaster search console. Secondly, many bots who look at your robots.txt file will then follow through to your sitemap file too - which is another way of helping make your site SEO friendly.

The entire sitemap.xml file should be saved at the root of your Jekyll project (aka alongside your index.md and other main pages) and look as follows:

---
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" 
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>{{ site.url }}/</loc>
        <changefreq>monthly</changefreq>
        <priority>1</priority>
    </url>
    {% for post in site.posts %}
    <url>
        <loc>{{ site.url }}{{ post.url }}</loc>
        {% if post.lastmod == null %}
        <lastmod>{{ post.date | date_to_xmlschema }}</lastmod>
        {% else %}
        <lastmod>{{ post.lastmod | date_to_xmlschema }}</lastmod>
        {% endif %}
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    {% endfor %}
    {% for page in site.pages %}
    {% if page.isresourcepage == null or page.isresourcepage == false %}
    {% if page.url != '/feed.xml' and page.url != '/404.html' and page.url != '/sitemap.xml' and page.url != '/' %}
    <url>
        <loc>{{ site.url }}{{ page.url }}</loc>
        <changefreq>monthly</changefreq>
        <priority>0.8</priority>
    </url>
    {% endif %}
    {% endif %}
    {% endfor %}
</urlset>

The isresourcepage is a way of me ignoring some resource pages like contact us, copyright/disclaimer, privacy policy (etc) from the sitemap file. The resource page I want to skip should therefore simply have the following in its front matter:

---
layout: page
title: Contact Us
description: The contact information for this website
permalink: /contact-us.html
isresourcepage: true
---

Lazy-loaded images and YouTube videos

Sites which are image heavy can be fairly expensive to load in the browser, and especially on mobile devices, if they load all images straight away. The natural solution to this is to lazy-load them, and something called IntersectionObserver is perfect for this (it detects if the user is about to view a particular HTML element, and then runs a JS callback - which in our case, we can use to ‘switch’ a lazy-loaded image to have an active src attribute).

The code for this lazy-loaded Jekyll plugin and JS is on Github but in general, the following Jekyll tag:

{% lazyload_image /path/to/image.jpg|Image description goes here|image classes here%}

Will generate the following HTML:

<img data-src="/path/to/image.jpg" alt="Image description goes here" title="Image description goes here" class="image classes here" />
<noscript><img src="/path/to/image.jpg" alt="Image description goes here" title="Image description goes here" class="image classes here" /></noscript>

My site Super Tiny Homes has a few images galleries, but hand-crafting the markup for this was fairly laborious so I wrote a quick Jekyll plugin which received a list of images and created an image gallery out of it. See a demo of this here.

I explain how this works in detail (along with naturally sharing all the code) on Github but the gist is that the following can be included in a post’s front matter:

---
title: Some title
(some other front matter)
image_gallery1_data:
    /path/to/image1.jpg|Some description here for the alt tag.
    /path/to/image2.jpg|Some description here for the alt tag.
    /path/to/image3.jpg|Some description here for the alt tag.
    /path/to/image4.jpg|Some description here for the alt tag.
---

And then the image gallery can be referenced as needed in the article:

{% image_gallery page.image_gallery1_data %}

The Javascript which powers the image gallery is vanilla JS (meaning that no JQuery or other plugins are needed) and it supports multiple image galleries on the same page.

10 newest articles across multiple (but not all) categories

If your site has multiple categories but you only want to show the N newest articles from a subset of these, then the following snippet should work well:

<ul class="recent-articles">
    {% assign actualarticles = site.categories.electric | concat: site.categories.hybrid | concat: site.categories.hydrogen | sort: 'date' | reverse %}
    {% for post in actualarticles limit:10 %}
        <li>
        {{ post.date | date: "%d %b %Y" }}:
        <a class="post-link" href="{{ post.url | relative_url }}" title="{{ post.description }}">{{ post.title | escape }}</a>
        </li>
    {% endfor %}
</ul>

In this case, I am only looking for articles relating to ‘electric’, ‘hybrid’ and ‘hydrogen’ (cars).


I’ll post more useful snippets as and when I come across them, so feel free to check back soon.