Skip to content

Jekyll Tutorial

Alexia edited this page Jan 28, 2019 · 7 revisions

What is Jekyll?

Jekyll runs GitHub Pages. It is what allows GitHub to automatically convert a repository into a website. It processes the branch called gh-pages as if it contained the source code of your website. If you download Jekyll onto your own machine, you can see how the site would look if you made changes, giving you a reasonable testing environment without you having to change and push the code into the repo untested. Jekyll is necessary because the files themselves are not complete web pages; it runs over them and makes web pages out of them. It is not necessary, however, to have Jekyll installed on your own machine unless you wish to test the view of the site in the way previously detailed.

The Tutorial

The purpose of this tutorial is threefold:

  1. To make sure you have everything you need to run Jekyll.
  2. To introduce you to the syntax and weirdness of Jekyll by running you through creating a simple site in Jekyll.
  3. To explain how Jekyll works with github, and what this means for GRNsight.

Let's begin!

Part One: Getting Jekyll

You can't do anything until you have jekyll on your machine. In order to install Jekyll, you need ruby and rubygems! Specifically ruby version 2.0.0 or higher. To get the latest version of ruby, you need homebrew! I'm going to assume you don't have homebrew, so if you have it, just skip this part. However, I suggest you go over it anyways, just to get the latest version of everything you'll need. Onwards we go!

As an aside before we get started, you may need to run the terminal commands with sudo. Some of them required it for me, but some didn't. If in doubt, use sudo!

Now to the tutorial.

Getting Homebrew:

Homebrew is lovely and you should definitely have it. Now if you go to the homebrew site to install it, you'll notice they give you a ruby command. If you already have ruby (macs come with it standard as long as you have xcode I'm pretty sure), then you can just run the command:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

in the terminal. If you're on a windows machine, you'll need to go through some extra steps, but we'll just assume that you're not for now.

Updating Ruby:

Alright, so you've got homebrew! Now just run the command:

brew install ruby

and you'll automatically download the latest version of ruby! Yay!

Getting RubyGems:

Alright, so you've got ruby, now you need rubyGems! Download the file rubygems-2.4.8.zip from here and extract it. Unzip it, then go your snazzy terminal and cd into the directory that you unzipped it to. Run the command:

ruby setup.rb

and you're good!

The Main Event: Jekyll!

So you've got all the prerequisites and now you're finally ready for to get Jekyll. Well, it's super easy! Just run this command:

gem install jekyll

and you have jekyll! Whew!

Part Two: Getting Acquainted with Jekyll

Jekyll is here to make your coding life easy. There are only four things you need to make a snazzy website with Jekyll, and I'll walk you through making a super easy simple site in Jekyll so that you can get down the basics.

First things first, decide a directory you want to keep your tutorial site in. I made a directory in my Documents directory called "jekylltut", but name it whatever you want. Now in this directory, you need four things to get yourself up and running (yes, the underscores are important!):

  1. A _config.yml file
  2. A folder called _includes
  3. A folder called _layouts
  4. An index.html file

Here's what your directory should look like after you get all those made. They can be empty for now:

The box in yellow is the important stuff. The stuff on the left is just the main directory and the absolute mess that I call my Documents folder.

Jekyll sees anything that begins with an underscore as a jekyll folder/file. That is, it will look at those folder and files specifically when rendering the static website.

So let's start at the top: _config.yml.

Making the Config File:

The _config.yml is basically - well, a config file for jekyll. It's what tells jekyll what to do and what properties to have. For our basic website, let's set up our _config.yml like this (this configuration was initially taken from here, and I edited it a bit since it was out of date):

Dependencies
markdown: rdiscount
highlighter: pygments

Permalinks
permalink: pretty

Server
destination: _gh_pages
host: 127.0.0.1
port: 3000
baseurl:
encoding: UTF-8

So now that's a lot of random stuff right there, but it's all important, even if not necessarily right now.

markdown: rdiscount allows jekyll to convert markdown to html, so you can use .md files instead of .html files when making your site! Now that may not be convenient right now, but there's a high chance GRNsight will be moving to markdown, so it's good to have. You can read more about rdiscount here, though there's not much to the documentation. This will likely come into play later, so I'll research more about it then.

highlighter: Pygments enables syntax highlighting of code on your webpage! That's pretty cool. There's some special formatting required to highlight syntax, and even though we won't use it now, it's still good to have. You can read more about pygments here.

permalink: Permalink basically just changes how the links on the site look. This is important because it changes how the links on the static site are generated. When set to pretty, the setting will cause links to be formatted like this: http://dondi.github.io/GRNsight/about/ instead of http://dondi.github.io/GRNsight/about.html. This will change how you'll need to do links on the page when linking between files, but we'll get more into that later.

destination: Now we're getting into the good stuff. The destination setting specifies where your static site will be generated. I set mine to be the folder "_gh_pages" - Jekyll will automatically create this folder for you, so there is no need to create it yourself.

host: The host should pretty much always be localhost. If you wanted to set it to something else, you could.

port: This is the port your testing site will be located on! What do I mean by testing site? Well, Jekyll allows you to preview your site live! The preview site, once you set it up, will be at host:port. So our preview site would be at localhost:3000. We'll get more into preview sites in a bit!

baseurl: Oh boy, this one is important. This specifies the base URL where jekyll will generate the site. The base URL by default is set to the main site, so it's blank. For something like GRNsight, it would be /GRNsight instead of blank, becuase we don't want to load dondi.github.io, we want to load dondi.github.io/GRNsight/. I hope that makes sense. Either way, I love this thing and we'll be using it to death, because you're required to use this to make GRNsight work. And also, it makes linking between files extremely easy.

encoding: This just specifies the encoding type. UTF-8 for the win!

Now that I've rambled on about the config file for 20 minutes and you've got a config file set up however you want, I'm going to go out of order and move to the _layouts folder. The _layouts and _includes folders are where the magic happens, and it all starts in _layouts.

Layouts and Includes

When you make a website, you have your usual collection of things you add, right? You add your <!doctype html> and your <html> and your <head> and your <body>. Then you put in all your content. Well prepare to have your mind blown, because Jekyll will change the way you have coded HTML all your life... sort of.

Let's make a file in here and call it default.html.

Open up this file and add in the usual:

<!doctype html>
<html>
</html>

NOW STOP HERE. The jekyll magic begins now! Where you would usually put the <head>, put this instead:

{% include head.html %}

Looks weird, right? Well, this is referring to a file that we're going to make in the _includes folder, called head.html! That file will contain the head section for all of the pages that use this layout! Cool, huh?

So now that the head is taken care of, let's make the body as per usual, except we're going to add one teeny tiny little new thing.

<body>
{{ content }}
</body>

Content is going to be the unique content for each page. We make this in the html files for each individual page - that is, for example, in the index.html file we created. We'll get to that later though.

That's all you need for now! Here's what my default.html file looked like after doing that:

Now you may notice something weird about the spacing. When Jekyll creates the static files, the includes and content are injected exactly as you've created them. Now, that may not make a whole lot of sense now, but you'll see what I mean later. Basically, I space it that way so that the spacing of the html of the static site isn't weird.

Now to make our include file for head.html! Go to the _includes folder and make a file called "head.html".

Edit that file, and instead of adding in the usual elements, just put in <head> and </head> The absolute only thing this file will contain is our header! Now you can just smoosh in between those two things exactly what you'd normally have in the head - a title, meta, and maybe some links to some stylesheets. For now, just put in the title and meta tags. Now for the title, I'm going to make my title look like this:

<title>{{ page.title }}</title>

{{ page.title }} is jekyll-ese for the title you give to the webpage using this layout! You'll see how that's used in just a bit when we start making our index.html. Here's what my header looked like when I was done:

Remember what I said about spacing? I'm leaving the spacing of this file like so you can see exactly what I meant by that later.

Alright, now that we've got out default layout and our one include, now it's time to actually make our index.html file! Open up your index.html file. At the very tippy top of the file, add this:

---
layout: default
title: My Site
---

This is called the "Front Matter". What does all of that mean? Well, the three dashes above and below are required for jekyll, so don't forget about those. "layout" specifies which layout you want to use for this file. For us, we only have one layout right now - default.html - so we'll chose the layout default. "title" is whatever you want {{ page.title }} to equal! Remember how our header title was page.title? Well, whatever you put in the "title" field will be made into your page title! You can add really anything you want up here so long as it isn't a reserved name in jekyll. They all serve as variables that can be accessed at page.variablename.

Now that you've added that to the file, let's actually put in some content! Anything you write in this page will make up the {{ content }} portion of the template. I'm going to just make a simple paragraph and write "Hello world" in it. Here's what my index.html looks like now:

Now we're ready to rumble! Let's make our site!

Running Jekyll:

Cd into your directory (for me, it's "jekylltut"), and run this command:

jekyll serve

It's going to spit out a screen that looks somewhat like this:

(note: you see the double slashes after 127.0.0.1:3000? That's because I was an idiot and had the baseurl at / instead of a blank for the first like.. 45 minutes of doing this tutorial. Don't do what I did. Yours shouldn't look like that. Jekyll will automatically append a / to the end of whatever you put in the baseurl if you have anything there, which resulted in a stupid double slash. That's also why above I said the baseurl would be "/GRNsight" not "/GRNsight/", because jekyll will add that ending slash for you. Anyways, enough rambling. Back to the tutorial.)

Remember what I was saying about a testing site? Well, this is your testing site! For me, it's hosted at 127.0.0.1:3000, also known as localhost:3000. So if I go over there, I can see the static version of my site! So if I go to localhost:3000, I'm met with this lovely screen:

Now the sweet thing about jekyll is.. you don't need to bring down the server in order to make changes! As you change files, jekyll will automatically regenerate this test site for you. I should probably note that you WILL need to reload for changes to _config.yml, because that is only read a single time. So if you change the config file, you may need to reload. For all other files though, you're good to go as soon as you save the file!

So say I wanted to change it from "Hello world" to "Hello worlds"? I could just go ahead and change it and then the change would appear on refresh. Pretty cool!

If you go into your directory, you'll see that there's a new folder that your static site has been generated in. For me, it's the folder "_gh_pages". Opening up this folder gives you the files for the static site. All I have in my _gh_pages folder is a lonely index.html. We'll change that in a bit.

BUT FIRST... Let's talk a bit about spacing.

Spacing:

When I refer to spacing, I'm not talking about the webpage that you see, I'm talking about the spacing in the code itself. So, let's take a look at the generated index.html in the "_gh_pages" folder. If you spaced your code exactly the way I did, your index.html should look something like this:

The spacing of the head and the paragraph are all off! That's because the content is injected into the html EXACTLY as you wrote it. So because I put in no spaces before the header or the content, all the spacing is wrong! Some people may not care about that, but I personally like my code to be spaced all nice and organized, so I'm going to adjust my header to have 1 tab (actually 4 spaces) over, and my content to have 2 tabs (8 spaces) over. So they look like this:

head.html

index.html

If you look at the terminal where your jekyll server is running, you should see something like this:

This means the site has regenerated! So there's no need to relaunch the server to see changes in your code! Re-opening the static index.html, we can see it now looks like this:

Much better! Be sure to keep spacing in mind when creating your includes. There may be some sort of option to change this, but I haven't found it for now, and it's not that big of a deal to space it out.

Enough spacing talk for now! Let's talk a bit about how you can use templates, and then make our site pretty.

Adding more webpages:

So the beauty of jekyll is that you only need to create one template, then insert content into it as needed. Let's make another file and call it "about.html". Put this in the same folder that your index.html is in (that is, don't make a new folder for it). Give it the same jekyll-ized front matter, using the default template and whatever title you want. Add any content you wish. Here's what my file looked like when I was done:

If you look into your _gh_pages folder now that you've added this folder, you'll probably notice that there is no about.html file. Rather, there is now an about folder containing an index.html! This means that if you want to link to this new file, you'll have to link to "about/" instead of "about.html". It makes the links look nicer, and is just something to keep in mind. I'm going to link to the about page in my index.html. The new index looks like this:

You can test out your site to see what this looks like. Now that we've added another page, let's start making these pages pretty.

Adding extra files:

Jekyll will ignore any folder that doesn't begin with a _ when it's generating the site. Because of this, we can store extra files like css, js, and images in any folder we choose so long as it doesn't start with an underscore! I'm going to go ahead and create a folder called "assets" in the "jekylltut" folder. Inside the assets folder, I'm going to make an additional folder: "css".

I'm going to create a css file called "main.css", and put it in that folder. In the css file, I'm just going to create a style that changes the background color to a light blue.

body {
background-color: #CEF7FF;
}

Now, we need to include this css file in our header! Inside the head.html file, I'm going to make a reference to the assets/css/main.css file. This is where baseurl comes in.

Remember that about.html is not located in the root directory - it's located in a separate folder called "about". If you tried to link the css file by using "assets/css/main.css", it would look for "about/assets/css/main.css" in the about page, since the header is the same for all of them! As a result, the css file would not apply to the about page, but would only apply to files that are in the root directory - which in this case, is only index.html. To get around this, we can utilize baseurl! Instead of making our link to our css file look like this:

<link rel="stylesheet" type="text/css" href="assets/css/main.css">

we should make it like this:

<link rel="stylesheet" type="text/css" href="{{ site.baseurl }}/assets/css/main.css">

That will make sure that every page with this header searches for the css files in the same spot (from the root directory) instead of from their own directory. Pretty cool! Now if you load your site, you'll see it's a nice shade of light blue, and our about page is also light blue!

Link js files, images, and the such in exactly the same way. You can use site.baseurl in any file that jekyll reads - that is, you cannot use it in js (for example, to change the mouseover logo image in GRNsight. You'll have to hard-code that.)

For the last part of this piece of the tutorial, I'm going to add an image to the about page. I found an awesome image of the mona lisa drawn with a graphing calculator in my downloads folder, so I'm going to throw that on my about page. In the "assets" folder, I'm going to create a folder called "images" and throw in that image of the graphing calculator mona lisa.

To link this to my about page, all I need to do is add in a reference to the image! When referencing the image, I'm going to use baseurl, since it can be used in the html pages too! So I added this line to my about.html file under my paragraph:

<img src="{{ site.baseurl }}/assets/images/monalisacalc.png">

After saving, I loaded up the page and was greeted with this:

Beautiful.

So some last few points:

  1. Use site.baseurl!
  2. When in doubt, check the generated static site file! Also check the generated js and such to make sure they're up to date if you're having problems!
  3. Keep good spacing (if you want)!
  4. The front matter is required on any page you want rendered with jekyll that isn't an include! Make variables in there and use them (see Step Three for more on this).

Part Three: Using Jekyll with GRNsight

Now that you've got jekyll and know some of the basics, mosey on over to the GRNsight repo. Make sure that you've pulled the latest, jekyll-ized version.

New requirements:

You'll notice two new files in the repo: Gemfile and Gemfile.lock. That Gemfile is basically like a rubygems version of dependencies with node. The Gemfile.lock file makes sure you get the exact same versions of the rubygems that I have. However, before you can use the Gemfile, there's just one more thing you need: Bundle. All you have to do to install bundle is run the command

gem install bundler

and you'll get bundle. Now you're ready to go!

To get started with using Jekyll with GRNsight, cd into the GRNsight repo and run the command:

bundle install

and it will install everything you need! Now you're ready to go.

You might notice is that there is no "_gh_pages" folder. That's because I put that in the .gitignore file. When you run the site locally on your machine, it will generate that folder for you. When you push the repo, that folder will be ignored. That folder can potentially break the way github handles the site, so.. make sure not to push that!

Adding Jekyll to GRNsight didn't overall change much other than the inclusion of includes and layouts. However, there are some differences that need to be addressed. The first thing I'll talk about is the way that you launch the testing site. Which, by the way, you can preview the GRNsight site easily before pushing to the server!

The testing site:

If you try to run "jekyll serve", you'll notice that it will throw errors at you. In gh_pages, you don't run jekyll serve. Instead, you run this command:

bundle exec jekyll serve

This will prevent anything from erroring out, so make sure to utilize that whenever you're wanting to test github sites.

I set up the _config.yml with two things that are different from the previous tutorial, and these will slightly change how you view the testing site. The first is the inclusion of a baseurl that is not blank. This is because, like I said before, the site is hosted on dondi.github.io/GRNsight/, not dondi.github.io. The second is the port. I made the port 3001 instead of 3000. Because of the inclusion of a baseurl and a different port, when you run "bundle exec jekyll serve", navigate to localhost:3001/GRNsight/ to view the site.

Changes:

I moved the "stylesheets", "images", and "js" folders into a folder called "assets", and also renamed the "stylesheets" folder to "css". You'll notice in main.js, I changed the file path for the mouseover to "/GRNsight/assets/images/..." to account for the fact that you can't use site.baseurl in javascript files, and also the fact that the pages are generated in folders now. You'll see this if you run jekyll serve.

You're going to see site.baseurl pretty much everywhere in the includes, as well as in some of the content html files themselves. This is to make sure everything renders properly.

More changes:

Aside from the billions of {{ site.baseurl }} inclusions, there's a few things that are changed. The two major things are the "modified" variable and the "version" variable (this is only in beta.html and index.html).

"modified" is exactly what it sounds like. If you modify a file, change the value of this variable. This will write into the last modified section of that page exactly what the last modified date was! This means that the last modified can stay in the same place it was before, while remaining dynamic for each page. The "version" variable on the index and beta pages are the same way. They just contain the current version. There is no longer a need to hunt down where the last modified date is or the version is. Just change those variables and jekyll will change it for you. Simple as that!

If you want to add something new to the sidebar or footer, the contents of both of those are located in "menu.html" (so changing that will change the content of both - yay!). All of the scripts we run are located in scripts.html.

I think that's about it! If you read the jekyll tutorial above, you'll be able to make your way around everything pretty easily.

Clone this wiki locally