Week 02

Things start to become clear. The first task of getting along with the GitLab system and build the first bit of the documentation website is a challenge nonetheless I have been making many websites before.

Looking for my Git documentation? Look no more, it has been done during the previous week. I also spent both weeks helping others to understand the secrets of Git, GitLab, HTML and the Internet in general.

Migrating to Hugo

Assuming that you have your website on your GitLab account and Hugo installed, you should navigate to your website folder in your file explorer (like Finder on Mac OS systems).

Make a new folder which will contain your Hugo site boilerplate. Call it something like hugo-site, but you can name it however you want.

Navigate to this folder in Terminal, on Mac you can do this easily by opening Terminal, typing cd and adding a space, then dragging and dropping the folder from Finder into the Terminal. Then type the following command in the Terminal.

hugo new site .

This should create the following file and folder structure there.

├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

Once you have it, you can open the folder as a project in a text editor, like Sublime.

subl .

Open the config.toml file. .toml stands for Toms Obvious Markup Language. It should look as follows.

baseURL = "http://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"

Change the title and add some extra parameters like in the example below.

baseURL = "http://example.org/"
languageCode = "en-us"
title = "Kris Fab Academy Documentation Site"

[params]
subtitle = "CAD, CAM and folks at the Fab Lab Barcelona"
description = "Fab Academy 2018 at the Fab Lab Barcelona from the perspective of Kris"
author = "Kris"

Note the [params] marker. It tells Hugo that it should add extra parameters to it’s black box of variables.

Now move the index.html file of your website to hugo-site/layouts. The file tree should look as follows now.

├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
│   └── index.html
├── static
└── themes

Now we are at the poing when we can test Hugo. In order to do that we can launch the Hugo development server. Make sure that you are in the hugo-site directory in Terminal.

hugo server

You should get the following output.

Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)

It tells you the address of your Hugo website http://localhost:1313/ that is hosted locally. Congratulations! Your website works! But wait, there is a problem, you can see no images there.

In order to add assets, such as CSS and image files, we need to make use of the static directory of your Hugo installation. Move all files, except *.html, hidden and README.md into the hugo-site/static/ directory. The hugo-site structure should look as follows now.

├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
│   └── index.html
├── static
│   ├── kroz.jpg
│   ├── style.css
│   └── zork.jpg
└── themes

Notice that we added two images (kroz.jpg and zork.jpg) as well as a CSS file (style.css). Now, when you run hugo server or if it is running already, opening your website in the browser at http://localhost:1313/, you should see everything as it was before. If you had multiple sections in your website, they would not work at this point.

We need to create a layout (or template) for all the sub-pages that we will have in our website. Create a directory with the name _default in the layouts folder and move one of your sub-section HTML files in there. Rename the HTML file to single.html The resulting folder structure should be similar to the one below.

├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
│   ├── _default
│   │   └── single.html
│   └── index.html
├── static
│   ├── kroz.jpg
│   ├── style.css
│   └── zork.jpg
└── themes

We are using a menu to navigate through our website. Since we want it to appear in all of our layouts, we will make it as a partial. For that create a directory partials in the layouts folder. Create a file with the name menu.html there. Cut and paste the HTML with the navigation part from your single.html so the contents of menu.html look similar to this.

<nav>
    <ul>
        <li><a href="index.html">Main</a></li>
        <li><a href="section.html">Section</a></li>
    </ul>
</nav>

Then, in single.html and index.html in the same location where the menu has to be, add the following Hugo template placeholder. Delete the old menu code.

{{ partial "menu.html" . }}

The sub-pages are not working yet. In order to make them work, we first have to add some content in the content directory of our hugo-site. Content has to be written in Markdown. Create the following file and folder structure in the content directory.

├── content
│   ├── about.md
│   ├── asignments
│   │   ├── assignment01.md
│   │   └── assignment02md
│   └── final-project.md

Let’s satart by editing the about.md file. Add content to it. It should look similar to the example below.

---
title: "About"
---

This section has information about my background.

- This is a list
- The second element of a list
- Third one

You can use *italics* and **bold** to emphasize your text. 

Note the part between ---, this is called the Hugo front matter. There you can define variable for your page.

{{ .Title }}
{{ .Content }}

First thought was to keep it plain HTML. During the on-line lecture about git, Fiore showed a few things about how continous integration works with the GitLab repositories of ours. I noticed that there was a CI template for Hugo static website generator.

Hugo is a static website generator written in GoLang. I have done programming in GoLang some time ago when I was building a resource management system for the Fab Lab Berlin. GoLang compiles fast, creates a dependency-less executable and is perfect for high performance web backend projects.

I have used Hugo before and currently it is my favorite static website generator. While building, I noticed that Hugo features that I am using locally, do not work with the Hugo version on the server. My conclusion was that the version on the server is outdated.

However, I discovered that there is a way to fix it without bugging others. It is the before_script: section in the .gitlab-ci.yml that is able to download and install a specific version of any software you might need. Below you can see my current CI configuration. It is based on an article that can be found here.

image: alpine

variables:
  HUGO_VERSION: '0.34'
  HUGO_SHA: 'b9aa1d54e83daa1f77c0794110d2d96064bc07431337742fec903f65f0606e6e'

before_script:
  - apk update && apk add openssl ca-certificates
  - wget -O ${HUGO_VERSION}.tar.gz https://github.com/spf13/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz
  - echo "${HUGO_SHA}  ${HUGO_VERSION}.tar.gz" | sha256sum -c
  - tar xf ${HUGO_VERSION}.tar.gz && mv hugo* /usr/bin/hugo
  - hugo version

pages:
  script:
  - hugo
  artifacts:
    paths:
    - public
  only:
  - master
  
test:
  script:
  - hugo
  except:
  - master

We are using two variables, HUGO_VERSION and HUGO_SHA here. HUGO_VERSION defines the version of Hugo we want to use. You can find out the latest version by visiting the Releases section on the Hugo GitHub repository. For each version there is a ..checksums.txt file, where you can find the value for the HUGO_SHA variable. It is used to verify the downloaded *.tar.gz file, if it is exactly the same as the one compiled by the author of Hugo.

Optimizing Website Images with Image Magic

Using Image Magic to optimise images for your website. Once you add images to your website manually, it sometimes happens that you add an image that is too big (too many megabytes). I have been always thinking of developing a repeatable workflow for a reliable way of adding images to a Git repository. The problem with images in Git is that if you add an image that is too big once, even if you replace it with a smaller one, the big version of it still remains in the Git history.

Git is not the main reason why one should do it for one’s website. People pay real money for downloading your mega-sized images. If you own a smartphone and are not lucky enough to live in a country with reasonable mobile data rates, each image that has not been optimised can cause unexpected personal budget fluctuations.

Before we begin, let’s assume that our website project structure is as follows.

.
└── website
    ├── images
    └── index.html

We are going to store our optimized images in the website/images directory. Where do we store the mega-sized source images. Hold on. We have to create a directory for images outside the git repository. Let’s call it srcimages.

.
├── srcimages
└── website
    ├── images
    └── index.html

You can download it on the ImageMagick website or install with Homebrew if you are on Mac OS X.

brew install imagemagick

It will install a set of command line tools for you to use. One of them is convert. If you have an image in the srcimages directory, we can use a script like the following, to resize and compress images and put them into the website/images folder.

convert srcimages/input.jpg -resize 900 -quality 65 website/images/output.jpg

I will explain the parameters that are used in the command above. -resize 900 means that we are setting the width of the image to 900 pixels. -quality 65 means that we are compressing the output image with 65% quality setting. In my case I managed to transform a 285KB 3000x1850px image into a 24KB 900x555px output.

How about a script that reads all images. The following script uses the mogrify command that is to be used with batch processing of images. You can find the explanation of the parameters in the Efficient Image Resizing With ImageMagick article by Dave Newton.

mogrify -path ./website/images -filter Triangle -define filter:support=2 -thumbnail 1000 -unsharp 0.25x0.25+8+0.065 -dither None -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB -strip ./srcimages/*

You can transform it into a little program that we can use by defining the final size of the image as well as input and output directories, avoiding all the parameters that we do not have to change. Create a script file and change its permissions to be able to run it.

touch convert.sh
chmod a+x convert.sh

Open it and paste the following code in it.

#!/bin/bash

INPUT_DIR=$1
OUTPUT_DIR=$2
OUTPUT_WIDTH=$3

mogrify -path $OUTPUT_DIR -filter Triangle -define filter:support=2 -thumbnail $OUTPUT_WIDTH -unsharp 0.25x0.25+8+0.065 -dither None -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB -strip $INPUT_DIR*

Use it like this. Make sure you have the trailing slash / at the end of the paths as the script does not check that.

./convert.sh srcimages/ website/images/ 800

And you have it! All the images are resized proportionally and now have the width of 800px.

Conclusions

This week I mostly spent helping others to set up their websites. Hugo is my tool of choice when it comes to creating websites these days. I was very sattisfied that I found a way to enable continous integration option on the Fab Academy GitLab setup.

What I learned this week was how to integrate Hugo with GitLab. I was also redesigning my web page from scratch. It used to have a rather darker theme.

If you are looking for the version control protocol part, I covered that part in the first week.