Jekyll to Jigsaw
Tags: blogging, opensource, productivity
Published: 2019-01-08 13:57:19

---
title: 'Jekyll to Jigsaw'
description: 'Some notes on the process of converting the static site generator I use from Jekyll to Jigsaw.'
published: true
tags: blogging, opensource, productivity
cover_image: https://thepracticaldev.s3.amazonaws.com/i/3yr4wck0vqclcvjsj4xt.png
---
All these _year in review_ and _New Year's resolutions_ got me motivated. I decided use it to complete one of [my own goals for the year](https://dev.to/gonedark/2018-lookbehind-lookahead-2019-4pnn) - redesign blog. This was more or less an impromptu hackathon, which I time boxed to 4 hours to ensure I didn’t go down the rabbit hole of intricately redesigning everything.

This would be a simple facelift to modernize the template with a focus on copy, as well as a conversion of the static site generator. I decided to refactor my blog to [Jigsaw](https://jigsaw.tighten.co/). So this serves as not only my first article to christen the conversion, but also a review of the process.

## Why JigSaw
My blog has been around for over a decade. I can't tell you how many times it's been converted. It originally started as static HTML, then _WordPress_, then _Jekyll_, then _GitHub Pages_, then _Ghost_, then back to _Jekyll_. And now, of course, Jigsaw.

Historically I used this as an opportunity to try new tech stacks. Nowadays, this is rather impractical for a few reasons.

1. A blog doesn't really push technical boundaries. So while it may serve as an introduction, it's not going to substantiate its use for other things.
2. My time is better spent elsewhere. If it's not a good learning opportunity, just go with something familiar. Jigsaw has a PHP core and leverages Laravel Blade templates engine. It also included a [starter template](https://jigsaw.tighten.co/docs/starter-templates/) developed with [TailwindCSS](https://tailwindcss.com/) and a little [Vue.js](https://vuejs.org/).
3. Both of these combined bring me to my final reason of convenience. Writing blog post is hard enough already, I don't want anything to make it harder. While Jigsaw allows me to use Blade, I can continue to use Markdown.

In the end, for me, Jigsaw balanced my time by being convenient to work with (PHP + Blade + Markdown) while still giving me some light learning opportunities (TailwindCSS + Vue.js).

## Converting front matter
Although front matter is pretty straightforward, I created a lot custom keys over the years while transitioning between all the static generators. So I wrote a quick script to condense these down (and reformat) to the minimal amount of: `title`, `description`, `date`, `categories`, and a few SEO keys.

Here's a [Gist of the conversion script](https://gist.github.com/jasonmccreary/af977128c87cb8404515f103e3141d7f) I wrote.

## Rewriting URLs
Another motivation for this redesign was to finally switch to [jasonmccreary.me](https://jasonmccreary.me). I purchased this domain a while back, but had not made it primary. Since I was going to change the link structure for each of my posts anyway, I took the opportunity to do both.

The key thing was ensuring my URLs redirected so I didn't lose my search engine rankings. I made sure to switch the proper settings in Google Search Console and Google Analytics, as well as generating `301` redirects for each post. There was also some tweaks to the Jigsaw config and template to ensure generated URLs consistently included the trailing slash.

Here's a [gist of these scripts](https://gist.github.com/jasonmccreary/2eef6508bba04703ce202612f76ececd) to convert the Jekyll posts dated filenames to the dasherized Jigsaw post filenames and generate the `301` redirects.

## Tweaking categories
For the most part Jigsaw was a straight conversion. The only thing that took a minute was configuring the categories. The documentation was a bit light on how these are set up (possible open source contribution…). Again since I was familiar with PHP and Blade, it wasn't too hard to dig around the code and figure it out.

Initially, it wasn't automatically generating the category pages (or collections). Ultimately, there is an `source/_categories` folder within the start template where I needed to create markdown files for each of my categories.

That wasn't quite it though. The `categories` closure in `config.php` also needed some tweaks. Especially since my category names were titles and contained spaces. I had two options, I could add code to generate the lowercase, dasherized URLs in the template or I could do so at build time.

Inline with my goal to keep the writing experience easy, I preferred to generate these properly at build time. So I changed the config to lowercase and dasherize the categories names from the front matter and properly group the posts. Here's the specific code as well as a [Gist of the complete `config.php`](https://gist.github.com/jasonmccreary/9890185a5cf9644b5bb1fa5fd772d263).

```php
'posts' => function ($page, $allPosts) {
    return $allPosts->filter(function ($post) use ($page) {
        $category = str_replace('-', ' ', title_case($page->getFilename()));
        return $post->categories ? in_array($category, $post->categories, true) : false;
    });
}
```

## Adding Read Time
Jigsaw also has fancy [helper methods](https://jigsaw.tighten.co/docs/helper-methods/). This is pretty nice as it was a pain to customize such things and Jekyll - often requiring overriding or monkey patching in Ruby. With Jigsaw I simply add a closure in `config.php` and can reference it through the `$page` object just like I do the front matter.

This made it super easy to create something I wanted to add to my articles for a while - _Read Time_. It's a nice little UX hack to see an estimate of the time it will take you to read an article. I derived the formula from some of [these calculations](https://marketingland.com/estimated-reading-times-increase-engagement-79830). Here's the specific code and also in the [Gist of the complete `config.php`](https://gist.github.com/jasonmccreary/9890185a5cf9644b5bb1fa5fd772d263). I simply call `$post->readTime()` within my templates.

```php
'readTime' => function($page) {
    return intval(round(str_word_count(strip_tags($page->getContent())) / 200));
}
```


All in all it took about 4 hours for the conversion. 2 hours were massaging the front matter, and another hour was battling the category configuration. So, in fairness, it really only took about an hour to set up Jigsaw using the starter template and begin customizing.

I plan to revisit the design, especially after reading [Refactoring UI](https://refactoringui.com/) and incorporate pages for my various [products](https://basecodefieldguide.com) and [services](https://jasonmccreary.me/articles/mentoring-pair-programming-development-coaching/). I like doing a little bit each time I write an article. I'll write a post and spend 15 minutes making other tweaks. So well I wouldn't call it done, I will check the box for my first 2019 goal of 2019 two redesign my blog.

_**Have more questions about Jigsaw?** Ask me here or on [Twitter](https://twitter.com/gonedark). I'm glad to answer and considering packaging up some of my customizations or contributing them to the starter template._