Intro

So what is this all about…

Jekyll

Jekyll is a simple, blog-aware, static site generator. It takes a template directory containing raw text files in various formats, runs it through a converter (like Markdown) and our Liquid renderer, and spits out a complete, ready-to-publish static website suitable for serving with your favorite web server. - website

GitHub Pages

GitHub Pages is a static site hosting service, and is designed to host your personal, organization, or project pages directly from a GitHub repository. - website

Resources

Getting Started

To install Jekyll you will need Ruby. If you are on Windows see jekyllrb.com/docs/installation/windows/.

Once Ruby is installed with all relevant platform dependencies, then install Jekyll and Bundler.

gem install jekyll bundler

Assuming you now have Jekyll installed, initialize a new site

jekyll new <SITE>

This will install the GitHub Pages Ruby gem by default, including the included minima theme.

Serve the site locally with the following

jekyll serve
# alternately, if you receive an error due to inconsitent installations
# between system and gemfile.lock (required dependencies)
bundle exec jekyll serve

Find the app hosted at http://localhost:4000/

Customization

With some creativity, you can hack your website into anything you want. But there is a lot of useful functionality out of the box with Jekyll. For example, make sure you understand how to use the following features.

Theme

To remove the default theme, remove the gem 'minima' in Gemfile, and remove theme='minima' settings in _config.yml. Otherwise import a local css/sass file to simply override theme settings.

Gems

Jekyll is written in Ruby, a programming language which refers to their libraries or packages as Gems, and therefore Jekyll uses Gems for third-party features.

Learn about Jekyll gems and the bundler

Additionally, plugins allow you to run some custom code to modify your site content even further. If you are using GitHub Pages, custom plugins are blocked.

To install a plugin, add the plugin to your config.yml file.

plugins:
  - jekyll-feed

and run

gem install jekyll-feed

Also, add gems to your Gemfile

group :jekyll_plugins do
   gem "jekyll-feed"
end

If you modify the Gemfile, you must then run bundle install

YAML Frontmatter

What the heck is YAML?

YAML is a human friendly data serialization standard for all programming languages. - website

It is basically a markup language used to store configuration data. Jekyll sites commonly use it to store data on blog posts like dates, and tags and the like.

Liquid for Automation

What the heck is Liquid?

“Liquid is an open-source template language created by Shopify and written in Ruby.” - website

It is basically a language for dynamically rendering templates without any server-side processing. But it also allows us to reuse (HTML) templates, embed templates in other templates, and combined with the Jekyll engine using YAML data, we can even programmatically access and render our entire site’s content. For examples, checkout the Code Snippets below.

Jekyll Engine

What do they mean by “Jekyll Engine”? It’s basically the combination of Ruby, Liquid and YAML to give you access to all site content dynamically. For more, refer to the Jekyll cheat sheet.

Plugins

Custom plugins can be written in Ruby and either stored in your _plugins dir, or installed through a Gem, and can add a lot of convenience and features to a site.

However, according to the Jekyll docs, custom .rb files do not run during build on GitHub pages since it is built in --safe mode. Therefore only install from available approved gems for now if you are hosting on GitHub pages.

Collections

Check out Jekyll’s documentation on Collections for added functionality. This site uses collections to manage “Notebooks” and “Projects”, separate from “Posts”.

Data

Check out Jekyll’s documentation on Data Files for added functionality. This site uses data files to manage added information on collections, like “Projects”.

This site uses a tool from Google to embed a site-wide Google Search. Find more about how to do this yourself at google.com/webmasters/.

If you want to find out how I created knanne.github.io/search, check out my code at github.com/knanne/knanne.github.io/search.

Search Engine Optimization

  • use the jekyll seo gem to auto-create valuable site properties
  • create a jekyll sitemap to be indexed by search engines. (upload this to Google Search Console)

Google Analytics is a great free way to track your sites activity, and learn specifics about your audience and traffic.

Blog

Most people use Jekyll for creating a blog, or at least sharing code snippets and notes in some form of posts. I am doing the same on this site.

Embedding Content

Of course in a basic HTML page, you have the freedom to create and embed whatever you want. If you are using markdown to create posts, it may be a bit more mysterious although possible none the less.

I have more detailed notes for my own reference on how to create posts for this site here.

And similar instructions for myself on creating notebooks.

Basic Content

  • use markdown syntax for adding code blocks, quotes, text formatting and the like. Refer to GitHub’s Guide on Mastering Markdown
  • add latex with math blocks $$...$$, enabled by MathJax
  • add photos with ![<IMAGE>](/path/to/image.png)
  • embed HTML inside a <div></div> container

GitHub Gists

Embed a larger code snippet, posted on GitHub Gists, by simply adding the following HTML in your markdown post.

<div>
  <script src="https://gist.github.com/<USERNAME>/<GIST-ID>.py"></script>
</div>

Jupyter Notebooks

Jupyter Notebooks are a popular way to code quickly, as well as share fully documented data science workflows. This site has fully embedded Jupyter Notebooks living at knanne.github.io/notebooks.

The easiest way to add a Jupyter notebook to your post is to convert it to HTML using nbconvert, then embed simply use Liquid to include it in your markdown post. The conversion from the command line would like something like this jupyter nbconvert --to html <NOTEBOOK.ipynb>, and to include it use {% include_relative path/to/<NOTEBOOK>.html %} making sure the post is in a subdirectory of the post (or use normal include if the notebook is in your _includes folder)

Note, you can always link to a free rendering of your notebook on Github using Jupyter nbviewer. An example link would look like the following: http://nbviewer.jupyter.org/github/<USERNAME>/<PROJECT>/blob/master/path/to/<NOTEBOOOK>.ipynb.

Site Comments

This blog implements the comments powered by Google Plus (see bottom of post). I have not found any official documentation on their web API site, but found sample code here, and a blog post describing the implementation here.

Other notable options I have seen include:

Social Buttons

RSS

This site uses the gem jekyll-feed for auto-creating a formatted RSS feed with post content. Find this sites RSS feed at knanne.github.io/feed.

Projects

As mentioned before, this site uses the Jekyll features Collections and Data to manage projects by adding the projects path to the site, and fetching project information from site.data.projects for displaying content. This site’s projects lives at knanne.github.io/projects.

Additionally, I use another nice free feature of GitHub Pages to host project repos, in the site’s path. Find out more about this from GitHub here. The key takeaways are: create a new project repo, go to the project’s Settings and select GitHub Pages > Source to assign from where you want to publish the project, and then simply view your project at your https://<username>.github.io/<projectname>. For example, check out knanne.github.io/vu_socialweb_2016/.

Code Snippets

Here are some code snippets that may come in handy when trying to code your own site. Some of these are implemented on this site.

Recent Posts Summary

{% for post in site.posts limit : 3 %}
    <h3><a href="{{ post.url | relative_url }}">{{ post.title | escape }}</a></h3>
    <p class="text-muted">{{ post.date | date: "%b %-d, %Y" }}</p>
    <p>{{ post.excerpt | strip_html }}</p>
{% endfor %}

Posts by Category List

{% for category in site.categories %}
    <h3>{{ category | first }}</h3>
    {% for posts in category %}
        {% for post in posts %}
            <a href="{{ post.url }}">{{ post.title }}</a>
            <a class="text-muted"><small>{{ post.date | date: "%b %-d, %Y" }}</small></a>
        {% endfor %}
    {% endfor %}
{% endfor %}

Post by Sorted Tags

{% capture tags %}
  {% for tag in site.tags %}
    {{ tag[0] | url_encode }}
  {% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}

{% for tag in sortedtags %}
{% assign t = tag | replace: '+', ' ' %}
  <h3 id="{{ tag }}">{{ t }}</h3>
  <ul>
    {% for post in site.tags[t] %}
      <li>
        <a href="{{ post.url }}">{{ post.title }}</a>
        <span class="text-muted"><small>Published: {{ post.date | date: "%b %-d, %Y" }}</small></span>
      </li>
    {% endfor %}
  </ul>
{% endfor %}

Customizing the Iteration of Site Content

{% assign projects = site.data.projects | sort: 'date' %}
{% assign projects = projects | reverse %}
{% for project in projects %}
  {% if project.publish == true %}
    ...
  {% endif %}
{% endfor %}

Automatic Table of Contents

The default markdown converter for Jekyll is Kramdown, which generates IDs by default for headings and allows for the auto generation of a table of contents. Simply include the following snipped in your markdown post file.

# Contents
{:.no_toc}

* Will be replaced with the ToC, excluding the "Contents" header
{:toc}

source from Kramdown docs

You can specify which headings to be used in the TOC in your config.yml

markdown: kramdown
kramdown:
  toc_levels: 1..4 # only using h1 thru h4 to generate table of contents in posts