This goes along with my talk at the 2016 North Houston .Net Users Group Lightning talks. It's an intro to Jekyll and GitHub pages.
Before we get into writing code, let's clear up exactly what this talk is about.
It's about Jekyll - A "simple, blog-aware, static site generator perfect for personal, project, or organization [web] sites."
It's about GitHub Pages.
We're starting from scratch. There are starter repos out there. Jekyll itself has a new command line option to get you a starter site. We aren't using these, as I'd like for you to understand Jekyll - not just be able to use it. Definitely explore these other options when you finish the tutorial though. Knowledge is power!
Here's what you'll need installed:
My demo will be shown from a Mac. But wait Jon! This is a .Net users group! We all run Windows... No problem. Everything I show here can be run from a Windows machine as well. Installing Ruby is a little more trouble on Windows, but not too much if you use RubyInstaller. Oh... and .Net runs on Mac and Linux now. The times, they are a changin'.
We're going to be focusing on getting a site built using Jekyll, ready to host on GitHub Pages - but we aren't going to push them to GitHub as part of this talk.
If you're interested in hosting your blog from GitHub, make sure you have a GitHub account.
Lastly, if you're on Mac all commands should work from the terminal. If you're on Windows, your best best is to run the commands from PowerShell, as it maps Unix-style commands to their equivalent Windows ones.
Find a location on your local drive where you store dev projects.
Make a new directory for your site. If you're going to be hosting a blog on GitHub Pages, then name the directory "username.github.io" where username is your GitHub username.
mkdir username.github.io
Initialize the repo.
git init
Add a .gitignore file
(On Mac/Linux)
touch .gitignore
(On Windows: PowerShell)
echo $null >> .gitignore
In your text editor of choice, add the following to the .gitignore file:
_site/
.sass-cache/
.jekyll-metadata
Commit!
git add --all
git commit -m "Initial Commit"
Let's install the Jekyll Ruby gem into our project.
gem install jekyll bundler
Configure the gems used by Jekyll. Create a new file named Gemfile and put the following inside it. This will limit Jekyll to using only what GitHub Pages supports.
source "https://rubygems.org"
gem "github-pages", group: :jekyll_plugins
Now let's install/update the github-pages gem (and all the dependencies). You'll notice some new ones install, some get upgraded, and some get downgraded.
bundle install
Let's get our first content put in the site. This will create an index.html with some awesome content.
echo "Hello World" > index.html
Time to test! Run the following to build your site and host it from http://localhost:4000 .
bundle exec jekyll serve
Success! ...with warnings. We'll get to those.
Open the web browser to http://localhost:4000 and you'll see:
Time to commit, as this is definite progress.
git add --all
git commit -m "Got Jekyll Working"
Create a new file named _config.yml
echo "# Jekyll Settings" > _config.yml
Open the _config.yml file.
When Jekyll builds the site, it includes nearly everything in the working directory in the output. Let's setup some exclusions. Add the following to the file:
exclude:
- Gemfile
- Gemfile.lock
- LICENSE
- .sass-cache
We can define site-wide values to refer to in this file as well. Add the following to the file:
# Site Settings
title: NHDNUG Rocks!
description: like a boss
Here's what the file should look like when you're done:
# Jekyll Settings
exclude:
- Gemfile
- Gemfile.lock
- LICENSE
- .sass-cache
# Site Settings
title: NHDNUG Rocks!
description: like a boss
Finally, let's test out our site properties in the index.html file. We'll setup the top matter and add some HTML that references both site and page properties.
---
title: "Home Page"
---
<!DOCTYPE html>
<html>
<head>
<title>{{ site.title }} - {{ page.title }}</title>
<meta name="description" content="{{ site.description }}" />
</head>
<body>
<h1>{{ site.title }}</h1>
<p>{{ site.description }}</p>
</body>
</html>
Build the site.
bundle exec jekyll serve
Great!
Time to commit. So far, we've got a working Jekyll site with site and page properties.
git add --all
git commit -m "Jekyll Config and Site Properties"
In order for us to focus on writing content and not HTML every time we want to create a page, we need to build some boilerplate HTML that wraps each of our pages. Jekyll calls these templates, and stores all of them inside a _layouts
directory. They are then referred to by a layout
property in individual pages and other templates.
We're going to be creating 2 templates, one for the overall branding and another for individual blog posts.
Create a _layouts directory
mkdir _layouts
Create 2 template files in the _layouts directory: default.html
and post.html
.
Copy the following into default.html
.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>{{ page.title }} - {{ site.title }}</title>
</head>
<body>
<h1><a href="/">{{ site.title }}</a></h1>
<hr />
{{ content }}
</body>
</html>
Copy the following into post.html
.
---
layout: default
---
<article>
<h1>{{ page.title }}</h1>
{{ content }}
</article>
Time to add our first post. Create a _posts
directory and then place a file named 2016-11-17-nhdnug-annual-talks.md
. Place the following within it.
---
layout: post
title: NHDNUG Annual Talks
date: 2016-11-17
---
the present day wast a most wondrous day. we consumed
lots of zza. code f'r life.
And why are we talking like Shakespeare?
We also need to adjust our index to display our posts. Replace what's in index.html
with the following.
---
layout: default
title: Home
---
{% for post in site.posts %}
<article>
<h2>
<a href="{{ post.url }}">
{{ post.title }}
</a>
- {{ post.date | date: "%b %-d, %Y" }}
</h2>
{{ post.excerpt }}
</article>
{% endfor %}
Time to test.
bundle exec jekyll serve
Index:
Post:
Looks pretty plain, but you get the idea.
Often, you'll have a piece of code that needs to be used in multiple places; or it's just complex enough that you'd rather put it in its own file. This is what Jekyll Includes are for.
Let's build a simple share button in an include.
Start by creating a _includes
directory.
mkdir _includes
Now create a share-button.html
file inside the directory.
echo " " > _includes/share-button.html
Place the following into the file:
{% assign share_url = include.url | escape | prepend: site.url | prepend : "https://www.facebook.com/sharer/sharer.php?u=" %}
<div style="display: inline-block; background: grey; border: 1px solid black;">
<a href="{{ share_url }}">Share on Facebook</a>
</div>
Now, add the include to the post layout file post.html
, making sure to include the post url as an include parameter.
---
layout: default
---
<article>
<h1>{{ page.title }}</h1>
{{ content }}
{% include share-button.html url=page.url %}
</article>
Lastly, let's add a url
property on the site object by adding it to the _config.yml
file.
url: "http://example.com"
Time to test. Stop the running server, then start it back up.
bundle exec jekyll serve
It's not the prettiest thing, but it's functional!
At this point, you've soon most of the core parts of Jekyll. With some content and a theme off the Internet, you too can have your blog hosted off GitHub Pages, with absolute control over the markup and the performance of static pages.