Jekyll
Jekyll is great. It generates a web-site based on templates, meaning that you edit templates to change things and generate static pages to serve then. Here are my notes on how to use it.
Installing
Installing jekyll on Debian is as easy as apt-get install jekyll
.
As Jekyll wants to process templates, you then need such templates.
If you are starting for the first time, it might be a good idea to
have Jekyll generate you a new site, which is easy too:
The created folder contains several files and folders, which together make up a site after being processes by Jekyll. So let us have a look at those:
- css/ - a folder to contain all your CSS files.
- _includes/ - a folder with files generating code to be included in other files being generated.
- _layouts/ - a folder with files specifying how certain content should look like.
- _posts/ - a folder for blog-style postings, including a demo post
- about.md - a demo about-page using markdown
- _config.yml - the one major configuration file for Jekyll
- feed.xml - an example on how to generate a XML feed
- index.html - an example for an entry page generating an overview of available content
Note the _
of some of the folders. Those mark special treatment by
Jekyll. The _config.yml contains central settings for the whole site.
Have a look at it with your favorite editor. It should look like this:
# Site settings
title: Your awesome title
email: your-email@domain.com
description: "Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description."
baseurl: ""
url: "http://yourdomain.com"
twitter_username: jekyllrb
github_username: jekyll
# Build settings
markdown: kramdown
permalink: pretty
You probably want to change title, email, description to your liking. The baseurl and url are worth a little more explaining. they will be used in the generation of links for your site, like url + baseurl + folder + page. So when you start generating your pages, wrong settings in these might lead to broken links. The usernames are examples that are used in the generated footer only, ignore them for now. Same goes for the build settings.
Building the Site
Now with the templates available and probably even your own name set,
you might want to run Jekyll the first
time to build your site. If you haven’t done so yet, go into the folder
and call Jekyll with the subcommand build
there:
Jekyll has analysed all files in the directory and generated your site
into the subfolder _site. Open the index.html file from _site in your
browser to view your site now. You can do so by just dragging and
dropping the file onto your browser if you cannot find the dialogue to
open local files. It will use an URL like
file:///home/user/test/_site/index.html
in the browser.
Like what you see? It means you are ready to go, in a
technical sense. You only need to provide the content now, to get your
site going. If you are working on the site and want to regularly rebuild
it, you can use the switch --watch
. This will cause the command to keep
running and automatically re-build the site if any of the content has
changed. But be warned that changes to _config.yml will not be recognised
by those rebuilds, so if you change anything there, then you need to stop
the running Jekyll and restart it.
Understanding the Build
Let’s have a look what Jekyll is doing here to understand the thing a bit. The index.html you are probably looking at has been generated, and I wanted to understand how. If looking at its source, i.e. test/index.html in the opposite to the generated test/_site/index.html, then we see it starts with some kind of special code:
---
layout: default
---
This is what’s called a front matter and always consists of the three hyphens at the beginning and the end. Between those there can be any number of variables declared, here it is only one.
Note: Only files with such a front matter are processed at all, so remember that.
The variable layout defines for it’s content, what file from _layouts is going to be used to generate it. So for this index.html we need to look at _layouts/default.html. This file contains the following:
This is a mixture of HTML tags (indicated by the < and >) and
commands for Jekyll (indicated by the {%
and %} ). Here, the code is putting the basic
HTML tags into the resulting document and including (importing) content
from head.html, header.html, and footer.html as well as the variable
content. Let’s look at the files first. Those are all in the
folder _includes, which is where the include command will look for them.
These are pretty important as they allow you to change the content of
all pages. Here is what they do:
- head.html specifies the head section to be used in all generated documents containing meta-data.
- header.html specifies a front part (by default the upper menu-bar) for all generated docuemnts.
- footer.html specified a bottom part (by default the footer with email, link to github and the site’s description) to all generated documents.
The variable content mentioned before does nothing more than add the content of your page, in this case the index.html with which we started above. Until now we only look at the front matter (header) of it. The rest of this index.html looks like this:
Again a mixture of HTML and commands for Jekyll. This time, only a middle part is defined. Here it is contained in a div-element. The commands in it iterate over all posts of the site (more on what that means - it’s not all of the site - later) and generates list-items for them. That basically means that if you add posts to your site, the generated index.html will automatically contain your new posts after the next build.
Adding Content
Adding content to your site is as easy as a creating a file and putting a front matter into it. You can use other formats besides HTML, I use markdown mostly. It’s much easier to edit. And you you can mix in HTML any time you need something more complex than markdown allows.
However, Jekyll treats different kinds of content differently, so its worth to learn about these differences first. You often want to have different kind of content on your site in the sense of different treatment, so this is really cool. But it adds complexity and needs to be understood. Basically Jekyll knows about these different kinds of content in the beginning:
-
Posts
Only content with a front matter within folder _posts will be seen as posts if they adhere to a naming convention composed of date, name, and extension (yyyy-mm-dd-name.ext). For example the automatically generated 2015-10-26-welcome-to-jekyll.markdown is a valid filename to put in _posts. Posts are the only content shown by the index.html discussed above.
-
Pages
All other files with a front matter will be treated as pages. These are not included in the list generated by the index.html as discussed above. Instead there is a similar loop as in that index.html in the _includes/header.html which will generate a list of all pages and as those as links to the header bar. Quite important to know …
-
Static Content
Everything not recognised as one of the above. These are not processed by Jekyll and instead are simply copied to the destination directory. This is how you want images and alike treated.
So let’s add content of each type as a training. Create a file in _posts with a valid name like 2015-10-26-test.md and put some simple content in like this:
---
layout: post
title: "test-post"
date: 2015-10-26 15:49:50
---
A test posting into my new blog.
If you generate your site (see above) you will notice the front page displaying your page. To add a page create a file named test.html in base directory and put some simple content in there like this:
---
layout: page
title: "test-page"
date: 2015-10-26 15:53:11
---
A test page for my new blog.
If you generate your site again (see above) you will notice that now the top bar has changed and contains the name of your new page as a link. Any static file will just be copied over, try to add a favicon to be displayed by the browsers to your base directory for example.
Styling and Organising Content
You know how to add content now. Let’s have a look at styling and ways of organising content, so you get a picture of the possibilities.
Styles
The above generates HTML code that is styled by the main.css in the css folder. The inclusion is defined in the header in _includes/head.html and thus gets used by all files. So to change styling, just open the css in your editor and add/change values. You can of course use different ids in the HTML tags and add styling information for those, too.
You can organise content by just putting files into folders without a _ in beginning of the foldername. However, the automatically generated menue listing all pages (but posts) will get annoying soon. It’s just for few pages, not for masses of such. To change what gets into the header, you can change the _includes/header.html file and adjust it to your needs. You can of course also remove the code that generates the entries and replace it with a static menue.
So this is easy if you know css. As a hint if you are new to this, many browser have debugging functionality build into them these days. In Firefox just right-click and use “inspect element”, and you will get a windows that shows you source code of the page as well as styles that got associated. You can even change values there temporarily to check out new values. Afterwards you just change the css file and enjoy the new look of your site.
Tags
Tags were something I stumbled upon early and had to deal with until lately.
Assigning Tags
You can easily assign tags to your content by including them in the front matter like this:
tags:
- i2p
- jekyll
This would add the tags i2p and jekyll to the page. Thing is, that at first nobody tells you what to ever do with those tags. Turns out its not that complicated though. Tags simply get added to the data-structures and can be accessed there.
Overview of Tags
I recently found out as described in the blog-post. So after assigning the tags, I wanted a page to display a list of tags and the blog-posts about it. I created a page tags.html in my base directory and put this into it:
Again the mixture of front matter (to get the file processed) and HTML tags + escaped Jekyll code to generated content. What the code does is to generate an array with all tags, sort it, and then iterate over that array and generate the tag name and links to all posts with that tag for each tag. This is how the tag-page is generated.
Tags on Posts
For blog posts, where I mostly use the ags, I then wanted to show what
tags had been associated with them. For this I will need to change
the layout used for posts, _layout/post.html
.
I first fiddled around with a structure
similar to the one explained above for the overview. But it turned out
to be much simipler, in the end. Here is what I added to the bottom of
that layout:
Instead of manually iterating over the tags, I here used the function
array_to_sentence_string
. This will take the list and output it with
comma and and as appropriate. So for two items in the list it will
output “1 and 2”, while for three “1, 2, and 3” and so on.
Categories
Categories seem to be a bit like tags. But I think I have seen folders being created for categories, so there is probably more to them. Haven’t found out yet. You can, however, treat them like tags and generate a page with all collections as shown above for tags. Will update this once I know more …
Collections
To organise content there is an experimental feature called collections. These basically allow you to create groups of content like posts and pages of your own types. It is currently not advised to use this feature on production systems, but let’s have a look. I’m using this here for the howtos, so let’s take them as an example. I extended the _config.yml with the following:
collections:
howto:
output: true
This defines a collection howto and sets its output-variable to true. Before explaining the latter, here’s how collections currently work. The folder _howto (or whatever name you gave your collection) is being reserved for this collection now. You put files into it, to add them to the collection. Only with the output-variable set as above will Jekyll process these files and generated according output-files. Without it, you can still process the data contained in those files but need to generate any output for yourself.
Now for the howtos, this document is saved as jekyll.md in my _howto folder. As the items of the collection or not getting linked automatically, I then further created a howto.html in my base directory. As such it will be a page and will be automatically shown in the header (if you don’t change what’s shown there as mentioned above). It will also get copied into the folder howto in the target directory. Now I only needed it to show all howtos. Here’s how I achieved that:
This is how currently the How-To-overview is generated.
Pagination
With the rising number of blog-posts the main page got worse to handle.
As it was so far showing all blog-posts, scrolling to the bottom became
like … work ;) I looked into pagination therefore and turns out this
already build in. Adding paginate: 5
will prepare data-structures,
but one needs to use them.
It’s rather easy though. Instead of iterating over all posts like in
the original for post in site.posts
, you iterate over the objects of
the created paginator with for post in paginator.posts
. That’s almost
it, the main content already gets displayed correctly. What’s needed in
addition is a page navigation.
This is a slightly modified version of the example code from the docs.
I added the distinction for paginator.previous_page == 1
because it
pointed at http:///
otherwise for the first page after I added the
/
after the generated links. That’s need for the index.html
to in
those folders to actually load.
Deploy: Publishing and Running Your Site on I2P
Running your site basically just means to copy the generated files to a web-server. But wait, why not generate them where you want them? Jekyll offers an option to specify the output-path, so if you are on I2P and want to publish your site, make sure:
- you have updated the sites url in _config.yml to your b32 address of the tunnel
- your user has the needed rights to write into the docroot directory
and then run:
jekyll build --destination /var/lib/i2p/i2p-config/eepsite/docroot/
You can use the --watch
switch here, too. But remember that it will not
recognise changes to your _config.yml (see below).
Hints & Pitfalls
Here some pitfalls I ran into and how to work around them and hints on how to achieve common things quickly …
Icon (favicon)
To have browsers display an icon for your site, include favicon.ico in your base directory (it will just get copied over) and include the following line in your _includes/head.html:
<link rel="favicon" href="/favicon.ico" />
Note that your browser might not recognise the new icon immediately. I guess it’s cached somewhere deeper within Firefox (in this case) then … Try with another browser if it should work but just doesn’t seem to …
Variables and Watch-Mode
I ran into a problem with changing the email-address displayed in the footer. There is a little note on the page explaining variables that explained my problem:
Jekyll does not parse changes to _config.yml in watch mode, you must restart Jekyll to see changes to variables.
So note that if you use --watch
you will do a restart if changing
variables in _config.yml
. I stumpled upon this with changing the
email as well as introducing collections.
ClearNet links used:
- http://jekyllrb.com/docs
- http://jekyllrb.com/docs/pagination/