Setting up Jekyll
General website setup
The most basic structure required is as follows:
$ tree $PROJECT_ROOT
website
├── Gemfile
├── _config.yml
├── _posts
│ └── 2019-01-01-post.md
└── index.md
Here’s a basic _config.yml
:
$ cat _config.yml
title: "Website"
email: "user@email.com"
markdown: kramdown
theme: minima
Technically, the Gemfile
is only required to compile and run locally. Github
does not require the Gemfile
to be part of the git repository. Here’s a
basic Gemfile
:
$ cat Gemfile
source "https://rubygems.org"
gem "minima"
gem "github-pages", group: :jekyll_plugins
Post file format
Jekyll can automatically detect and generate html for new files added in the
_posts
subdirectory. The post file name and contents need to be in a specific
format for this to work.
-
File name must be of the format:
YYYY-MM-DD-some-name.[md|markdown]
. -
The post file must have a front matter at the top.
Overriding the default theme layouts
Create a directory called _layouts
in the $PROJECT_ROOT
and add your
own templates (*.html
files). Any templates here will override the theme
defaults. New templates can also be added to the same directory.
Here’s an example:
$ tree $PROJECT_ROOT
website
├── Gemfile
├── _config.yml
├── _layouts
│ └── post.html
│ └── projpage.html
├── _posts
│ └── 2019-01-01-post.md
└── index.md
A page can inherit from any of the globally or locally available layouts.
Setting up tags
It seems like most of the articles online are either outdated or incorrect.
The clean and idiomatic way of accessing all the tags is as follows:
{% for tag in site.tags %}
{% endfor %}
Here, each tag is a two-tuple: tag[0]
refers to the tag name; and tag[1]
refers to a list of posts with the given tag.
So, to iterate over all tags and all posts for each tag, one can do something like:
{% for tag in site.tags %}
<ul>
<li>
{{ tag[0] }}
<ul>
{% for post in tag[1] %}
<li> {{ post.title }} </li>
{% endfor %}
</ul>
</li>
<ul>
{% endfor %}
There’s no way for Jekyll to generate the tag-specific pages (a page per tag) automatically. One would need to go outside the framework and write a wrapper script (e.g., using Python) to generate the tag-specific pages.
A workaround, I figured, is to put a list of all the tags (and their corresponding posts) in a single page and create hyperlinks to the tag anchor from the post page. See the example code here and here. Here’s a cleaner example:
For the single page with all the tags:
{% for tag in site.tags %}
<ul>
<li id="{{ tag[0] }}">
{{ tag[0] }}
<ul>
{% for post in tag[1] %}
<li> {{ post.title }} </li>
{% endfor %}
</ul>
</li>
<ul>
{% endfor %}
For the post page:
{% for tag in page.tags %}
<a href="/tags.html#{{ tag }}">{{ tag }}</a>
{% endfor %}
Writing Liquid code in Posts with Jekyll
See here. (This post also uses the workarounds mentioned on the above linked page.)
Jekyll with VSCode
I ended up developing a small VSCode extension, jekyll-post, to ease some of the pain of creating new posts using VSCode.
There aren’t that many extensions for VSCode that can automatically create a new Jekyll website and help manage the website (build, deploy, etc). There’s definitely room for a new extension here.