My goal here is to dynamically generate pages like /categories/code/, that would list all articles categorized in code. As far as I can tell, there’s no standard way. I found a few articles explaining how to create such pages for a given category, but none regarding how to auto-generate them for all your categories.

For this purpose, I resorted to some scripting, which through the power of CI, is completely transparent.

The process is:

  1. Create layout for category page
  2. Generate a JSON file containing the list of categories.
  3. Generate a page for each category using the layout in 1.
  4. jekyll build


The layout I used ressembles a lot the layout of the home page. In the _layouts folder of Jekyll, I created this file:

layout: default

<div class="home">

    &#123;&#123; content &#125;&#125;

    <h2>About "&#123;&#123;page.category&#125;&#125;"</h2>

    <ul class="post-list">
        &lcur;% for post in site.categories.&lbra;page.category] %&#125;
            <a href=""><span class="post-title">&#123;&#123; post.title | escape &#125;&#125;</span><br/>
                <span class="post-meta">&#123;&#123; | date: "%Y-%b-%-d" &#125;&#125; | &#123;&#123; post.categories | array_to_sentence_string &#125;&#125;</span>
        &#123;% endfor %&#125;

This basically iterates through the posts of a category contained in property category of a given page using this layout.

Category list

In my assets folder, I created an assets.json file with the following contents:

  "categories": [
      "Reading notes",
      "Code like a monkey",
      "Design patterns",
      "Self improvement",
      "Source control",
      "Coffee script",
      "Functional programming",
      "Small batches",
      "Product management",
      "Azure functions",
      "Quick note",
      "App Services",
      "API Management",
      "Self organization",
      "Quick post",

The --- tell Jekyll to build the file. The rest is just simple liquid. When building, the result looks like this.

Generate a page for each category

The page is plain and simple:

layout: category
category: Code

We just need to generate one for each in a categories folder, so that they can be accessed through /categories/code/.

Let’s start with a simple node script running through the categories.json:

const path = require("path");
const fs = require("fs");

const categoryFile = path.join("_site", "assets", "categories.json");
const categoryFolder = path.join("categories");

const categoryContent = fs.readFileSync(categoryFile).toString();
const deserializedCategories = JSON.parse(categoryContent);
const categories = deserializedCategories.categories;

categories.forEach(function(category) {
  if (category === "")
  const content = "---\nlayout: category\ncategory: " + category + "\n---";
  const file = path.join(categoryFolder, category + ".md");
  fs.writeFileSync(file, content);

I then invoke that in my build script:

#!/usr/bin/env bash

function build {
    if [ "$1" != "--refresh" ]; then
        jekyll build --incremental
        jekyll build

function updateCategoryPages {
    if [ -d "categories" ]; then
        rm -rf categories
    mkdir categories
    node build/updateCategories.js


The first build is going to generate the categories.json file. Then we iterate through it and generate files. Then we build again.

Having my build done on Codeship, all I need to do is push and this is done automagically.