Website Part 3: More Advanced Jekyll
In my previous article, I talked about how to get setup using Jekyll. I also mentioned in the title how Jekyll’s templating allows you to develop websites a lot more quickly. In this article, I will go over some more advanced features of Jekyll that will really boost your web-dev productivity.
Data Files & For Loops
There are many situations where you have a lot of data you want to put on your webpage — this could be lists of text or just just plain paragraphs. It is still a good idea to abstract this out into its own section, however front matter variables might prove to be a very untidy way of doing things. This is where data files come in. Jekyll’s templating engine can process CSV, JSON, and YAML files and plug the data they contain into your markup. Let’s see how this is done with a navbar.
<!-- This is vanilla HTML code for a navbar -->
<nav>
<a href="/index.html">Home</a>
<a href="/about.html">About</a>
<a href="/projects.html">Projects</a>
<a href="https://medium.com">Blog</a>
</nav>
This case is manageable, with only 4 links in the navbar. But if there were many more links, maybe nested in dropdowns, with very long href links, it would quickly get out of hand. This is where data files come in, combined with for loops. Create a directory in your website directory called _data
and create a file called navigation.yml
in it:
# _data/navigation.yml- name: Home
link: /index.html
- name: About
link: /about.html
- name: Projects
link: /projects.html
- name: Blog
link: https://medium.com<!-- navbar code in index.html --><nav>
{% for item in site.data.navigation %
<a href="{{ item.link }}">{{item.name}}</a>
{% endfor %}
</nav>
The navigation file is pretty self-explanatory: it just lists titles and links for the different navigation items. However, the XML code shows something new — for loops. If you have coded any other language, you probably know of for/foreach loops — they are a way to loop over a list of information. The syntax pretty much means “loop through everything in site.data.navigation — which references _data/navigation.yml
— and for each entry, store it in the variable item
and execute the template code between {% for … %}
and {% endfor %}
.
There are multiple benefits to doing this:
- You keep your links, etc. in a separate file, so you can edit that instead of the markup when you want to add or change a link.
- When you change the number of links, the for loop automatically changes the number of elements outputted, so you don’t have to manually set the number of items.
- You only have to write the template element once, which means easier to read, write, edit, and debug the markup!
Layouts
Nobody wants to write the same
<!doctype html>
<html>
<head>
<title>Jekyll is Awesome!</title>
</head>
<body>
<h1>Jekyll is Great!</h1>
</body>
</html>
for every page they have in their site. What really matters is the bold content inside the <body></body>
. Of course, most modern editors can fill in template code like this for you — but readability still goes for a toss with large headers. Let’s see how we can use Jekyll’s layouts to get rid of this boilerplate! Create a new directory _layouts
and paste the following content in _layouts/default.html
:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale='1'">
<title>{{ page.title }}</title>
</head>
<body>
{{ content }}
</body>
</html>
Now replace index.html
with the following code:
---
layout: default
title: Jekyll is Awesome!
---
<h1>Jekyll is Great!</h1>
Notice that we are using front matter to reference the layout named default
which we just created. Since the layout references {{ page.title }}, the title
variable must also be defined in the front matter — and this is great, since we can change the title of our page by just changing one variable. After the front matter, we have just the content that was previously bolded — Jekyll will automatically plug that in where {{ content }}
is referenced in the layout file! In this manner, you can create different pages with completely different content (and titles too) that all have the same metadata, <link>
s, and <script>
s.
Includes
Layouts are great, but they are somewhat limited in what they have to offer. Take the example with the navigation element — we can put that in a layout file as well, but not only do you have less control, but it is also not as modular as it could be — what if on one page, you wanted the navbar in a different location? (I know, probably not, but you get the idea) What we want in this case is a chunk of code with our navigation element that we can plug into our code wherever we want. Jekyll allows us to accomplish this with includes. To create an include, make a new directory _includes
and paste the following content into _includes/navigation.html
:
<nav>
{% for item in site.data.navigation %
<a href="{{ item.link }}">{{item.name}}</a>
{% endfor %}
</nav>
Now in index.html
, replace your <nav></nav>
code with {% include navigation.html %}
— it’s that simple. Now, wherever you put the include statement, Jekyll will plug in your navigation component! In a similar way, you can create footers, forms, or anything else that you want to reuse multiple times — for those savvy in other programming languages, think of using functions as opposed to writing out the same block of code multiple times. Even if you aren’t reusing markup code, it helps development efficiency tremendously to keep your code small an modular.
Assets
You are probably wondering by now where to keep your images, JS, and CSS files. Lets go over assets!
Assets are stored in the assets
directory — no underscore. Under assets, create the directories css
, images
, and js
. Put a jpeg image in the images
directory. In your index.html
, add <img src=”/assets/images/img.jpg”>
(replace with your image name). Note that you need to add a leading /
in the path to the image.
CSS and JS work in a similar manner — add the appropriate <link>
and <script>
elements to your layout file. However, we can go one step further with CSS and make use of Sass. For those who aren’t familiar, Sass (Syntactically Awesome Style Sheets) is a CSS extension framework, bringing variables, math calculation, nested tags, and more to normal CSS. I won’t go over how to code Sass here — take a look at https://sass-lang.com/. Using Sass in our website requires a few steps:
- Make a new directory
_sass
- Paste your CSS into
_sass/main.scss
: - Paste the following into
/assets/css/styles.scss
:
---
---
@import "main"
Now you can link /assets/css/styles.scss
in your layout file.
And that’s it! There is a lot more to Jekyll than I was able to cover in this article, including (but not limited to) themes, blogging, CoffeeScript, and more! Check out https://jekyllrb.com/ for more information!