This site Demo

Project stats

  • Difficulty: medium 3/5
  • Cost: 0€
  • Time: ~15h

The idea

The idea originated through my MobFobAmp project of which I didn’t have a github repository as there was no code or similar documentation to keep. So I decided I wanted a website so I could host instructions for this Open Hardware project for others to build their own copy. I wanted an easy-to-host solution that wouldn’t take too much work to set up. As I don’t have an own server, I asked for help. moritzmar recommended to use github pages as a site host to start with for easy auto-deployment and global scope. So I gave it a try.

Getting started

I figured out that a static site would be the right thing to use, without the need for a database or huge Content Management frameworks as my site layout should be simple and minimalistic; I just wanted to host this one project in the beginning. Github recommended to use Jekyll

Jekyll Logo
Jekyll Logo [ 1 ]

as a site generator. I had some trouble with the Windows Subsystem for Linux (WSL) as it wouldn’t accept my terminal inputs at some point, so I followed the guide and used the RubyInstaller which worked right out of the box for me.

Site setup

I realized that I might want to document more of my projects, and not only the “hardware” ones. That’s why I came up with the idea of grouping projects together, each with a header, a little teaser text, and a thumbnail image. Clicking on which would lead to the individual project page. Which would involve a lot of programming for page setup and layouting which I didn’t want to spend too much time on - my other projects were waiting…

First try with Themes

So I followed another suggestion by Github pages: The usage of pre-defined “Themes”. I first used the Agency Theme. This one has a great landing page with a huge picture and it supports collections that enable the group-the-project thing that I wanted. Unfortunately, the theme is a “remote theme” so customization was limited, e.g. I didn’t manage to have a colletion point to another page, it would always open a “popup” and I just didn’t want this. (Later, I figured out that remote layouts can be overridden, but that was too late so I already switched to another theme supplier…) The theme I’m currently using the Minimal Mistakes Theme (see site footer) which is very well documented. After downloading and a couple of first steps, I struggled with custom colors (_sass) and the collections - again - as I didn’t understand at first how Jenkill would do the bindings behind the scenes. Some of my struggles can be found in the Blog posts from June 2021.

Site layouts: hero screens

A bit of thinking should go into how the site layout should be like, to make navigation easy and intuitive. The approach will differ with every page type due to differences in complexity and document structure. landing heroTake the landing / home page for example, I want the navigation to be sticky so that the site’s categories are always visible. It shall receive a huge, wide overlay image with the page description. Below, latest posts will be listed. This is the example for the collection’s page hero screen: Image: collection hero The projects and their contents shall contain a page navigation in the left sidebar, may contain a scrollable header image, and has a wide setting to display a high amount of text in the content area. Image: project hero

The “hero screen” scetches for this site’s layouts can be found here.

Collections

Collections are a great way for grouping content. Look at my Open Hardware Projects page. You can find all projects in this category with a little teaser image and description here to get an overview.

This is how the collection’s configuration can work out:

  • Think of a fitting name for your collection, e.g. electronics.
  • Collection name is defined in _config.yml as collections: electronics.
  • Collection name has to be set in #defaults as type: electronics so that Jekyll knows how to interpret the actual content.
  • Collection page has to be created (e.g. in the _pages folder) with the attribute collection: electronics. This is the page that will actually display the overview of items in the collection.
  • Content folder with the same name as the collection’s name with leading underscore has to be created: _electronics.
  • All documents in this content folder will show up in the collection page automatically after a full build.
  • These documents should get a “front matter” (section before the actual content in the file, marked with ---) so that they can be displayed as described in the corresponding _layouts file, e.g. collection

More than the standard Theme

I have overridden some theme default and I’m using most of the existing Theme infrastructure. But my site has a couple of special needs so I had to customize and add Theme features. These are described in the following sections.

As my site navigation tree is pretty flat and I don’t have lots of pages to navigate to, I wanted the left sidebar to hold the page navigation rather than the site navigation. Thus, I wouldn’t need a right sidebar at all, so that there would be more space for the page content.

Table Of Contents on the left

As written here and there, I never was 100% happy with the way my project pages looked like: Image: project page before I setup toc_left The original idea of the theme is that the content is framed by two sidebars: The left one can either display Author information, custom content, or the site navigation. The content area is configurable between wide and normal, in the latter case leaving space for a second sidebar on the right. The right sidebar is configurable to not be there at all or to show the page’s table of contents.

So the target I set was to eliminate the right sidebar for my design, and instead of having the site navigation in the left sidebar, move the page navigation there.

Where the sidebar design is defined

It’s all about the /_layouts folder that keeps information about how a page layout should look like. The page design in question is called single.html and it at some point calls include sidebar.html which resides in /_includes/sidebar.html. So I thought of a new value I could use to control showing the table of contents within the left sidebar, chose toc_left and added a condition:

<div class="sidebar sticky">
<!-- ...
{.% if page.toc_left %}
    {.% include toc_left nav=page.toc_left %}
{.% endif %}
... -->
</div>

(By the way: I had to comment-out and add .’s to the jinja code, Liquid would otherwise interpret these as commands!)

Implementing the Table Of Contents

I wanted it to show up in the left sidebar container. So I just had to create a toc_left file that would call the included toc generator like this:

<aside class="toc_left">
<nav class="toc" markdown="1">
<header><h4 class="nav__title"><i class="fas fa-file-alt"></i>
<!-- ...
{.{ include.title | .default: site.data.ui-text[site.locale].toc_label }}</h4></header>
{.% include toc.html sanitize=true html=content h_min=1 h_max=6 class="toc__menu" skip_no_ids=true %} 
... -->
</nav>
</aside>

Audio Embeds

Audio embeds are these little player-like things on a website, often forwarding to a streaming platform or similar. I need them for some of my audio projects like this mobfobamp: just a caption and the player below. Image: embed-audio This post helped me a lot, so I could just add it to the _include, modify it a bit, and it worked!

Placing the favicon

I followed this guide to place a favicon for the site and it worked flawlessly. Image: favicon The favicon’s path has to be valid independently of the folder the rendered page resides in. I had to add ../ according to the pages’ depth within the site’s folder structure to make sure that the favicon could be displayed not only on the “home” page, but also from sub-paSges.

Optimizing for search engines

As my site was not found by search engines for a couple of weeks, I decided to perform so-called “SEO” (search engine optimization). That’s why I added jekyll-seo-tag and e.g. reworked all my links following Juliette Sinibardy’s SEO 101. When complete, I put my webpage through Lighthouse’s web-analysis audit. Image: Lighthouse Audit results For a first try, I think it looks pretty well. Biggest issue on the performance side seems to be CSS overhead.

Content Security Policy

The Lighthouse audit revealed that it would be a good idea to restrict external scripting to my site, so I introduced a Content Security Policy (CSP) like this:

webrick:
  headers:
    Content-Security-Policy:
      default-src 'self'
      script-src 'self';
      connect-src 'self';
      img-src 'self';
      style-src 'self';
      font-src 'self';

Initially, unfortunately, my home page’s backup image wouldn’t show, my embed-audio files wouldn’t play and all icons loaded externally were gone as well. Adding media-src: 'self'; and some more reading in Jakob Wilforss’ blog and especially Lighthouse’s recommendation helped to solve this. By using the Browser’s Web developer Tools, I figured out the missing resources the theme is loading in the background, so my updated CSP looks like this:

webrick:
  headers:
    Content-Security-Policy:
      default-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/; 
      script-src 'self';
      connect-src 'self';
      img-src 'self' 'unsafe-inline' https://upload.wikimedia.org/wikipedia/commons/ https://raw.githubusercontent.com;
      style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/;
      font-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/; 
      media-src 'self'; 
      object-src 'none';
      base-uri 'none';

Update

By the end of 2021, I chose to not have the page user download external resources from Wikimedia or FontAwesome, but decided to serve that content locally. This way, there’s no third party anymore registering calls to their content - plus, my page load times drop a little. I was able to revert changes to my Content Security Policy to the first example (but added media-src 'self';) above without side effects.

Errors

I’m collecting some simple errors here that cost me quite some time fixing.

Jekyll serve: UTF-8 incompatible character encoding

Image: bundle error when front matter is missing You enter bundle exec jekyll serve and get a strange UTF-8 “incompatible character encoding” error? The cause is simple: One of your files most likely has no header that can be converted into the front matter of the page that is generated from that file. Just add your usual header to your file like so and it will just work:

---
title: "Feeds and Speeds database"
excerpt: "for (light) CNC milling machines"
header:
  image: "blah/testimage.jpg"
[...]
---

Webpage is not being displayed at all: 404

This error was very, very hidden. I found it by accident browsing my site online only, as localhost serve was not affected. The symptom is a no-show blank page, not even my custom error page would come up.

Cause: Due to translation, my paths are getting longer and I wanted subpages to not have extremely long links. That’s why I was using the permalink: Attribute of the pages’ fontmatter. Now, only if you have a “trailing slash” here, the page will display on the remote server.

# Wrong:
---
title: "This Page won't be displayed"
permalink: /projects-software/pageerror
# [...]
---
# Correct:
---
title: "This Page will be displayed!"
permalink: /projects-software/nopageerror/
# [...]
# Unfolds on the english blog to:
# https://blog.schallbert.de/en/projects-software/nopageerror/
---

Site hosting

This site itself is a normal Gitea repository. It is built automatically with Gitea Actions once changes are added to the repository’s main branch.

Update Jan-2024

I moved my site from Github Pages to Gitea. I’m self-hosting both Gitea and the site now. Still, the site content is available as a repository and I can easily update and maintain it where I deem fit.

Summary

To get familiar with how Jekyll creates the site, how the theme would interact with my commands and how to override Theme behavior cost quite a couple of hours, but I think this site has a clear structure and a more or less “professional” look - And I didn’t have to write a single line of JavaScript or HTML to get this done. Nice!

  • Contents written in markdown *.md
  • Basic site configuration in YAML _config.yml
  • Page layouts written in html and jinja *.html, placed in _layouts and _includes
  • Page variables and appearance in SASS *.scss, automatically generating css files

Contribute?

You have ideas, criticism, or interesting stuff you’d like to let me know? Get started on my Discussions page!