Save 50 Hours Setting up Your Jekyll Blog
Spoiler: Just fork mine.
When I decided to start blogging, I explored all the major blogging platforms. I quickly came to the conclusion that, in order to get exactly what I wanted, I would need to have full control of the design and code.
As a Ruby developer, Jekyll was a natural choice. Jekyll is a static site generator that’s
“blogging aware”. “Blogging aware” means that Jekyll has conventions for managing your blog posts. You put all your
posts in the _posts/
folder. Jekyll generates pages for them and gives you template variables to index through
the pages.
In addition to supporting blogs out of the box, Jekyll had everything else I wanted:
- Good themes
- Support for source-code highlighting
- Posts can be written in Markdown
- Easy integration with Github pages (free hosting!)
- Support for layouts, partials, and other features that make it a pleasure to use.
- Easy to get your head around the entire site. No magic. Nothing is hidden.
Jekyll Incorporated Theme
The next thing I needed was a theme. I quickly settled on Jekyll Incorporated. It’s clean, simple, and very “Medium-like”. Thanks Kippt, Inc. for sharing this awesome theme with the community.
Jekyll Incorporated was built to be easily customized via config.yml
and main.css
. So I thought I would
just fork the theme and customize it for my needs. It would be easy, right?
In theory that was probably right. But I noticed a few minor problems with the responsive design of the theme. The blog cover images weren’t resizing nicely as they were in the demo site. I realized that this was because Kippt had made improvements to their blog after open-sourcing the theme.
Improving on Jekyll Incorporated Theme
I figured I would fix the cover images and then start writing posts. But that one fix revealed other issues in the code. One change led to another. I ended up making 40 commits in all. To make this harder on myself, I didn’t just tear into the code. I made all the changes in a way that could be merged back upstream, preserving the design and original intent of the theme.
None of this is to take away from the original work Kippt, Inc put into the theme. They created an awesome foundation for me to build on. There’s no way I could have done this on my own.
Remove Bootstrap.css
I noticed that the theme included bootstrap.scss
, containing all of Twitter Bootstrap. But none of the
Bootstrap features like the grid, forms, or typography were being used. bootstrap.scss
was only
providing a CSS reset (a cross-browser foundation to build the rest of the css on top of) and a few scattered,
random styles.
To fix this, I pulled in my favorite css reset: normalize.css. I then methodically went through bootstrap.scss, commenting out chunks, and looking for rules that were still being used by comparing the before and after pages in two browser tabs.
When I was done, I removed bootstrap.scss
and moved the rules that were still being using into into base.scss
.
Below are the rules I needed to save
The net change was 1647 lines of css removed. Here’s the commit
Improve source-code highlighting
Out of the box, Jekyll supports source-code highlighting using pygments.
You don’t need to know anything about pygments. Wrap your source code in highlight
tags and
it “just works”.
Is rendered as
1
2
3
4
5
class User < ActiveRecord::Base
# Wow this Ruby source code highlighting looks great!
has_many :user_assignments, :dependent => :destroy
has_many :hospitals, :through => :user_assignments
end
The theme already included Github’s syntax highlighting stylesheet: syntax.css. I added a few rules to clean up the look and prevent long lines from wrapping.
Before improvements
1
2
3
4
5
6
7
8
9
class User < ActiveRecord::Base
has_many :user_assignments, :dependent => :destroy
has_many :hospitals, :through => :user_assignments
# Ugly, but 5x faster than op2 and op3
# Takes 2ms
scope :grid_fields, -> { joins('LEFT JOIN user_assignments ON user_id = users.id LEFT JOIN hospitals ON hospitals.id = hospital_id').
group('users.id').select([:id, :name, :email, :role, 'min(hospitals.name) as first_hospital_name']) }
end
After improvements
1
2
3
4
5
6
7
8
9
class User < ActiveRecord::Base
has_many :user_assignments, :dependent => :destroy
has_many :hospitals, :through => :user_assignments
# Ugly, but 5x faster than op2 and op3
# Takes 2ms
scope :grid_fields, -> { joins('LEFT JOIN user_assignments ON user_id = users.id LEFT JOIN hospitals ON hospitals.id = hospital_id').
group('users.id').select([:id, :name, :email, :role, 'min(hospitals.name) as first_hospital_name']) }
end
Thanks Dmitri Moore for the ideas. Here’s the commit
Clean up config.yml
My philosophy on code and config is: the less the better. I went through config.yml line by line, referencing the Jekyll documentation and Googling information as needed. Almost everything could go. Most of the config items were simply re-stating Jekyll’s defaults. I also removed references to alternative markdown parsers, such as rdiscount, maruku, and redcarpet. Jekyll defaults to Kramdown for parsing markdown. Unless you’re doing something really specialized, there’s no need to deviate from this default.
The net change was 56 lines of config removed (the remaining config was almost all theme-specific)
Here’s the commit
Fix feed.xml
I don’t know much about RSS. I don’t even know if anyone will use it. But since RSS was already in the theme, I decided to keep it and fix it. Most of the fixes were obvious. I used the W3C Feed Validation Service to check the feed and Googled the errors I couldn’t figure out on my own.
Here’s the commit. Update: I’ve made more changes.
Add Github icon
I wanted to have a link to my Github profile in the social icons. The hard work was already done for me by @vdragsic. I tweaked the icon size to make it easier to see. This led to some weird rendering behavior and strange css that had to be cleaned up.
Before tweaks. Notice Github icon is small and not immediately recognizable. All social icons are too low.
After tweaks.
I broke this change into two commits: Add Github icon and Tweak styling.
Remove unused css rules
I went through and cleaned up all the unused css rules. Unused rules add to page weight and, more importantly, add to the cognitive load reading the css.
Tracking down the unused rules wasn’t hard. Since I wanted a better understanding of the css, I did it by hand. I searched for each rule in the css, deleted the ones that weren’t used in the HTML, making sure I didn’t break anything along the way.
These changes are in two commits: Commit 1 and Commit 2
Much more…
There are a lot more fixes and refinements. You can see all the detail in the open_source branch. Feel free to use this as a starting point for your blog. Maybe the changes will be merged back into Jekyll Incorporated. I submitted a pull request. But it’s a lot of changes to merge back upstream.
Development continues
In the meantime, I’ve moved ahead with my blog and have started making non-compatible changes to customize the theme for my needs. These include more css fixes and design refinements. If it’s something that looks useful, feel free to fork the master branch to get the latest.
Additional resources
Mike Greiling has some great articles on Jekyll on his blog (PixelCog).
Jekyll From Scratch - Getting Started
Jekyll From Scratch - Core Architecture
Jekyll From Scratch - Extending Jekyll