<< Go back to Posts
Warning : This document is still a draft

Jekyll Cheat Sheet

When you are not a front-end developer, starting a website is hard, as you do not know what are the tools available nor the way to do that. Historically, I started hosting my website on Neocities. I generated pages with pandoc, adding a template, this was far from being efficient. I discovered jekyll. Now, everything is so easy, works without running complicated scripts. I discribe how I started and some tips and trics.



Introduction

This post is a list of tips and tricks for jekyll, and how I started my website.


Setting up a Website

Finding an Hosting Service

A static website is a set of pages and directories. They are built once, and do not change over time.

What you need to access your website is a kind of “online repository” where you can request pages.

Long time ago, I discovered neocities, which gives for free 1Go for hosting many kind of files. This is more than enough for a personal website.

HTML, CSS, JS

There are three main “programming” languages to know:

  • HTML, which helps to create the structure of a page
  • CSS, which adds style, color, fonts, …
  • JS, which is used to add interaction.

You need to know the basics for each. However, you do not need to be an expert. (Conserning me, I do not know at all how to build CSS files from scratch. I always search for pieces of code online which implement the behavior and copy/paste).

Starting with a template

Today, you never start a website from scratch:

  • there are libraries
  • there are templates

As I am not a front-end developer, I am unaware of what is the best framework to develop my website. So, I selected the second option: use a template. I recommand it if being a web-dev is not your goal.

Instead of reinventing the wheel, there are plenty of templates available for free. You can search your own there:

Be careful with the license: free doesn’t mean you can do anything you want with.

Now, you need to custom it a little bit, changing colors, columns location, fonts, …

Automated Page Generation with Jekyll

Each time you create a page, you do not want to copy/paste your template to inject your content. There are automatic tools that do the job for you. Here, I use Jekyll.

Jekyll is a tool that allows to transform easy-to-write markdown files into HTML pages. Additionally, it allows to run your website locally, so you can see the direct result.

To start with, I recommand to test their examples to understand how it works progressively.

I won’t detail the basic exemples, but some more advanced that are less documented on the web. (Their documentation is a good start, but you may like additional examples).

Making and using a Layout

The first thing you need to define a layout (stored into the _layouts/ folder, see the documentation).

It is an html page where you define areas where your content, your title, and all other metadata must appear. To get this ready:

  1. Take an html page from on template found online
  2. Remove the initial demo content
  3. Add liquid markup to indicate where items go

From the template, you need to keep unchanged the head, the scripts, but you need to remove most of the body stuff. You need to keep some div, to get the page adjusted.

<!DOCTYPE html>
<html class="no-js">
    <head>
    <!--- your scripts there
    !--->
    </head>

    <body>
      <div class="container">

      
              {{ content }}
              

      </div>
    </body>
</html>

A layout page can also inherit from another layout page.

For instance, I have:

_layouts/
    base.html
    project_page.html

My project_page.html inherits from base.html.

---
    layout: base
---

	<div class="container">
		<a href="{{ page.project_base_url }}"> << Go back to {{ page.project_name }} </a>

      <br>
      {% if page.draft == true %}
        <i> <b> Warning </b>: This document is still a draft </i>
        <br>
      {% endif %}

      <br>
	      <center>
		      <h1> {{ page.title }} </h1>

      {{ page.description }}
      <br>
      <img src="{{ page.main_image }}">
	      </center>

      <br>
        {{ content }}
        <br>

  <p style="text-align:center">
	  >> <i>You can subscribe to my mailing list <a href="{% link signup.md %}"> here </a> for a monthly update. << </i>
  </p>
			</div>
		</div>

The yaml header indicates the parent template. I could add other variables.

In my project pages, I want to add an header and a footer:

  • the header (before the content) contains the title, description, image, and a draft mention if the article is still in progress.
  • the footer (after the content) contains a link to the signup page.

Filling a Page

Anywhere on your jekyll folder (expected _site/ and other _xxxfolder/), you can add .md documents.

It must contain a yaml header with at least the layout used:

---
  layout: main_page
  title: This is a title
---

Here is my content

If you do not set the layout variable, jekyll will no compile the page.

The layout liquid tag,

    {{ content }}

will be replaced by Here is my content, with all css styles applied.

When you set a variable within the yaml header, it becomes accessible within the template. For instance, you can print the title variable in your template by using the liquid syntax:


  {{ page.title }}

There are some reserved variable names, but you have plenty of choices.

Posts

In a website, you may want to have a “post” section, sorted by date, plus an automatically generated page to access them.

Posts are particular markdown files located in _post/ with the syntax yyyy-mm-dd-Whatever_name_you_like.md.

In the yaml header, you need to specify the category. For instance category: foo would lead to the creation into _site/ of _site/foo/yyyy/mm/dd/Whatever_name_you_like.html

Note: You do not need to create the foo/ folder ! All is done automatically.

If you do not want an article to be published yet, put it into _draft/ folder. They won’t be transformed into html, unless you run jekyll serve --draft.

Pagination

Ok, you have your post published. Now, you would like to have pages with 5-10 post summaries with a link to the full content. Here, you must do several things:

  • Install gem packages,
  • Update the Gemfile with the paginate package
  • Update the _config.yml file
  • Create a folder where your pagination pages will be, for instance my_website/blg/
  • Create an index.html in this folder

Install Package

Here, there is no secret recipe:

gem install jekyll-paginate-v2

Note: there are several pagination packages: jekyll-paginate, jekyll-paginate-v2. Please refer to their documentation. They are not compatible.

Update the Gemfile

This operation is useless, unless you want to git/clone your repository: you would need to install the correct package. The Gemfile is here to remind you what is necessary.

I needed to add this line:

gem 'jekyll-paginate-v2', '~> 3.0'

Update the _config.yml

plugins:
        - jekyll-paginate-v2

pagination:
  enabled: true
  per_page: 6
  sort_reverse: true

I first define the plugin I used, jekyll-paginate-v2

Then, I configure it.

  • I want 6 posts per indexation page
  • I want the newest first

There are other keywords available. Check the documentation for more info.

Create a Pagination Folder

You need to create a folder where pagination pages will be located. Posts will not be located there.

For instance, my_website/blg/.

Next, you need to create within this folder an index.html template page. This is a kind of layout page, but located outside of the _layouts/ folder. This page is like a layout page: you can have a yaml header to inherit from another template, add variables, or have pure html.

You need to fill this page with some info specific to pagination.

---
  layout: main_page
  pagination:
    enabled: true
---


{% for post in paginator.posts %}
<h1><a href="{{ post.url }}">{{ post.title }}</a></h1>
  {% if post.description %}
    <p>
      {{ post.description }}
    </p>
  {% endif %}


    {% if post.main_image %}
      <img src="{{ post.main_image }}" width=50% >
    {% endif %}

{% endfor %}

<!-- Pagination links -->
<div class="pagination">
  {% if paginator.previous_page %}
    <a href="{{ paginator.previous_page_path }}" class="previous">
      Previous
    </a>
  {% else %}
    <span class="previous">Previous</span>
  {% endif %}

  <span class="page_number ">
    Page: {{ paginator.page }} of {{ paginator.total_pages }}
  </span>
  {% if paginator.next_page %}
    <a href="{{ paginator.next_page_path }}" class="next">Next</a>
  {% else %}
    <span class="next ">Next</span>
  {% endif %}
</div>

The for loop under the yaml header allows printing post title, image, and description.

The part under the <!--pagination links --> displays “previous / next” buttons to access the other index pages.

Testing

You may need to restart jekyll to have the pagination working.

Filtering by Categories

You can group posts by category, and get different pagination pages.

categories and category are reserved names.

  • category is for one element
  • categories is when you define a list of elements

On a post, you can set one category

  layout: project_page
  title: This is a test page.
  category: project

You may want to list all items related to it.

In an index.html pagination page, using the Liquid syntax:

---
  tag: project
---

<ul>
  {% for post in site.posts %}
    {% if post.categories contains page.tag %}
    <a href="{{ post.url }}">{{ post.title }}</a>
    {% endif %}
  {% endfor %}
</ul>

Here, note the difference between page and post.

  • page is the current page, so page.tag = project.
  • post is one element stored into the _post/ folder.

In the page, you could replace tag variable by another variable, say toto: project. There, you would need to write if post.categories contains page.toto.

Filtering by tags

When you write a post, you can often classify it into many topics, so it is hard to choose a single one. Instead, you could add into your metadata a list of tags that best describe your page.

Here, I propose an example to list within a single page all posts with a particular tag in.

Suppose you have a blog post where you set in the yaml header:

  tags:
    - web
    - programming
    - blog

Then, on a regular page, you can list all the post about a particular topic.

---
  tagx: programming
---

List of post with "{{ page.tagx }}" included:

<ul>
  {% for post in site.posts %}
    {% if post.tags contains page.tagx %}
    <a href="{{ post.url }}">{{ post.title }}</a>
    {% endif %}
  {% endfor %}
</ul>

Here I names tagx the tag to find, to show the difference with tags which is a list.

Other Tips and Trics



>> You can subscribe to my mailing list here for a monthly update. <<