The other day, I built a small Jekyll website for Simplified JavaScript Jargon. If you are not familiar with the project, it is a community attempt at explaining JavaScript related buzzwords in simpler words to prevent JavaScript fatigue and ease adoption for new comers.
The project has long lived as a self-sufficient GitHub repository (gaining a bit of traction and a lot of stars in the process), but I wanted to given a nicer way for users to browse it. Hence a small Jekyll website.
The thing is, I did not want to make the GitHub repository non-usable anymore. Basically, I wanted everything to work both on GitHub and on jargon.js.org. Tricky! I eventually found a way, not without a struggle though so here are a few lines to explain the process.
The main problem
SJSJ is community-driven. It means that while I take care of the repository and the technical setup, I do not write entries (anymore). Generous contributors do that. They submit a pull-request to add a new Markdown file in the repository, and voila. I wanted this process to remain as simple.
The main problem is that when contributors want to link to another entry from their content, they do something like this:
Redux is an alternative to [Flux](/glossary/FLUX.md) and used a lot together with [React](/glossary/REACT.md), but you can use it with any other view library.
When clicking such a link on GitHub, it will head to the file FLUX.md
file located in the glossary/
folder for instance. Very good. Except that I needed these links to work the same on the Jekyll website.
One source of content. Two ways of browsing it. Two URL structures. A lot of troubles.
How I tried to solve it
I cannot change the way GitHub works (or can I…?), so if I want the entries to be consumable and linkable from both GitHub and Jekyll, I need to dig on the Jekyll side.
It turns out Jekyll 3 has lovely support for collections. And the nice things with collections, is that you can output pages, iterate on them and even specify the permalink you want. Neat.
I created a glossary
collection, containing all the Markdown files, outputting pages at /glossary/<path>/
:
collections:
glossary:
output: true
permalink: /glossary/:path/
A few problems there already. For starters, a collection folder has to be prefixed with an underscore (_
) in Jekyll, so the files would actually live in /_glossary/
but served over /glossary/
. Secondly, in-content links are rooting to /glossary/<path>.md
, not /glossary/<path>/
so they were broken. Bummer. There has to be a way.
How I actually solved it
The first issue is easily fixed by tweaking the permalink configuration to serve files over /_glossary/
to have a 1:1 mapping between the folder structure and the URL routing:
collections:
glossary:
output: true
permalink: /_glossary/:path/
I thought the second problem would be harder to fix, but it turns out I could simply serve entries with a URL ending in .md
. I believe under the hood all this is just URL rewriting, so it was not an issue at all.
collections:
glossary:
output: true
permalink: /_glossary/:path.md
Tada! Files are located at /_glossary/<path>.md
, served over /_glossary/<path>.md
. 1:1 mapping, site is browsable in both GitHub and Jekyll seamlessly.
Final thoughts
Admittedly enough, this is kind of an odd use case to want content to work on both GitHub and a custom website, but I think SJSJ is a good candidate for that.
Thanks to Jekyll friendly handling of permalinks and a bit of trial and error, it turned out to be quite simple to do.