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">

    <article class="post" itemscope itemtype="">

  <header class="post-header">
    <h1 class="post-title" itemprop="name headline">Fixing error CS2012 on Visual Studio for mac</h1>
    <p class="post-meta">
      <time datetime="2017-05-16T00:00:00+00:00" itemprop="datePublished">2017-May-16</time>
           | <a href="/categories/Code">Code</a> | <a href="/categories/.Net">.Net</a>

  <div class="post-content" itemprop="articleBody">
    <p>I encountered this bug that left me a bit circumspect while trying to give a shot at Visual Studio for mac and .net standard.</p>

<p>My setup was the following:</p>

  <li>Visual Studio for Mac community version 7</li>
  <li>Two projects with .net standard 1.4 (as far as I can tell, does the same thing for other versions), <strong>A</strong> is depending on <strong>B</strong></li>

<p>When re-building the project, I was encountering an error when building the .net standard project.</p>

<p>The issue it gives is fairly expressive, as you can tell:</p>

  <p>CSC : error CS2012: Cannot open ‘/Volumes/DIKS/git/events-client/source/EventServiceClient/obj/Debug/netstandard1.6/EventServiceClient.pdb’ for writing – ‘Sharing violation on path /Volumes/DIKS/git/events-client/source/EventServiceClient/obj/Debug/netstandard1.6/EventServiceClient.pdb’</p>

<p>So basically a file conflict on trace maps.</p>

<p>This seems to be a bug<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>. Despite some googling around, nothing seemed to be linked.  I finally realized that my solution is on a FAT drive, which does not handle I/O the way a HFS drive does. Moving the solution to an HFS drive does the trick!</p>

<p>Hope it can help someone.</p>

<h1 id="notes">Notes</h1>

<div class="footnotes">
    <li id="fn:1">
      <p>that I <a href="">logged here</a>&nbsp;<a href="#fnref:1" class="reversefootnote">&#8617;</a></p>


  <div class="post-related">
    <ul class="post-list" id="list">

  <script type="text/javascript">
    var title = "Fixing error CS2012 on Visual Studio for mac".replace(/[^A-Za-z0-9=_-]/g, "");
    document.searchClient.related(title, function(err, res) { document.searchClient.display(res.slice(0, 4)); });

    <h2>About ""</h2>

    <ul class="post-list">

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",

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.