The essentialist developer, part one

01 Dec 2019

Over the last 5 months, I have published well over 100 articles. Now that I have enough content, it's time to build my new site. I decided to stick with using Jekyll, as it's pretty powerful and will let me do all of the things I have in mind at the moment for my new site.

I'm going to document the whole process for building my new site.

Setup blank Jekyll Site.

mkdir the-essentialish-developer && cd the-essentialist-developer git init bundle init vim Gemfile

Add the following line to the end of the Gemfile, to enable jekyll on my project:

gem "jekyll" bundle

I use the Gitmoji command-line client to write commit messages. It lets you add an emoji to the start of your commit message (you can add them yourself, but I like that this provides a searchable list of emojis attached to meanings for consistent commit message types). I follow an imperative style with my commit messages "Do this so that".

vim index.html

Add "Hello World!" to the index

bundle exec jekyll serve vim .gitignore

Add following to .gitignore:


_site/
.jekyll-cache/
.jekyll-metadata

Setup node-sass

npm install node-sass --save-dev npm init echo node_modules << .gitignore mkdir sass && cd sass touch main.scss

Add following script to "scripts" section of the package.json file, so that my sass files automatically compile on every sass file save after running the "sass-watch" command in the terminal (npm run sass-watch)."

"sass-watch": "node-sass sass/main.scss css/style.css -w"

In root directory add place to automatically compile CSS code:

mkdir css && cd css && touch style.css

Then add css directory to .gitignore file so that it can't be committed (as it will be automatically generated from the sass files.

echo css/ << .gitignore

Setup accessibility test git hooks (can't commit without passing accessibility tests

Full article on how I did this here

That's the initial setup (Yak Shaving) done. Next step is to create a default layout for each of my pages (boilerplate html with metadata)

Boilerplate HTML (default layout) for Jekyll pages

Create a folder called "_layouts" and add a file to that folder called "default.html". Inside that file, include the following code:


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">

    <meta name="author" content="Rebecca Williams">
    <meta name="description" content="">

    <meta property="og:image" content="/assets/images/og-images/">
    <meta property="og:description" content=" ">
    <meta property="og:title" content="The essentialist developer, part one">

    <title>The essentialist developer, part one</title>

    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    

Exploring Liquid templating language

Liquid is a templating language which I am exploring to figure out how to make my static website appear to be more dynamic.

All liquid code can be categorised into 'objects', 'tags' and 'filters'. Objects tell liquid where to display content on the page: {{ page.title }}. Tags create the logic and control flow for templates {% ... %}. Tags can be categorised into: Control flow, iteraton and variable assignments. Filters change the output of a Liquid object {{ "world!" | capitalize | prepend: "Hello, " }} . Multiple filters can be used on one output, and they are applied from left to right.

Operators

  • == equals
  • != does not equal
  • > greater than
  • < less than
  • >= greater than or equal to
  • <= less than or equal to
  • or logical or
  • and logical and

{% if product.type == "Shirt" or product.type == "Shoes" %}
  This is a shirt or a pair of shoes.
{% endif %}

Contains

Checks for the presense of a substring inside a string, or the presence of a string in an array of strings. It can only search strings.


{% if product.tags contains "Hello" %}
  This product has been tagged with "Hello".
{% endif %}

Truthy or falsy


{% if happy %}
  Happy and you know it!
{% endif %}

Even empty strings are truthy.

Types

You can initialize Liquid variables using the assign (creates a new variable) or capture (captures string inside of opening and closing tags and assigns it to a variable) tags.

  • String:"This is a string"
  • Number:25, 39.756
  • Boolean:true, false
  • Nil: empty value returned when Liquid code has no results.
  • Array: holds a list of variables of any type.

You can access items in an array using iteration tags:


<!-- if site.users = "Tobi", "Laura", "Tetsuro", "Adam" -->
{% for user in site.users %}
  {{ user }}
{% endfor %}

You can use bracket notation to access items in an array:


{{ site.users[0] }}
{{ site.users[1] }}
{{ site.users[2] }}

You can't initialize arrays in Liquid, but you can use the split filter to break a string into an array of substrings.

Whitespace control

Use a hyphen to remove white space before or after strings (or both): {%- -%}

Tags

Comments


Anything you put between {% comment %} and {% endcomment %} tags
is turned into a comment.

Control flow

If


{% if product.title == "Awesome Shoes" %}
  These shoes are awesome!
{% endif %}

Unless


{% unless product.title == "Awesome Shoes" %}
  These shoes are not awesome.
{% endunless %}

elseif/else


{% if customer.name == "kevin" %}
  Hey Kevin!
{% elsif customer.name == "anonymous" %}
  Hey Anonymous!
{% else %}
  Hi Stranger!
{% endif %}

case/when


{% assign handle = "cake" %}
{% case handle %}
  {% when "cake" %}
     This is a cake
  {% when "cookie" %}
     This is a cookie
  {% else %}
     This is not a cake nor a cookie
{% endcase %}

Iteration

For


{% for product in collection.products %}
  {{ product.title }}
{% endfor %}

Else


{% for product in collection.products %}
  {{ product.title }}
{% else %}
  The collection is empty.
{% endfor %}

Break


{% for i in (1..5) %}
  {% if i == 4 %}
    {% break %}
  {% else %}
    {{ i }}
  {% endif %}
{% endfor %}

Continue


{% for i in (1..5) %}
  {% if i == 4 %}
    {% continue %}
  {% else %}
    {{ i }}
  {% endif %}
{% endfor %}

For loop parameters

  • Limit: {% for item in array limit:2 %}
  • Offset: {% for item in array offset:2 %}
  • Range: {% for i in (3..5) %}
  • Reversed: {% for item in array reversed %}

Cycle


{% cycle "one", "two", "three" %}
{% cycle "one", "two", "three" %}
{% cycle "one", "two", "three" %}
{% cycle "one", "two", "three" %}

output:
one
two
three
one

Cycles can be used to apply odd/even classes to rows in a table. You can also use them to apply a unique class to the last product thumbnail in a row etc.

Tablerow


<table>
{% tablerow product in collection.products %}
  {{ product.title }}
{% endtablerow %}
</table>

OUTPUT:
<table>
  <tr class="row1">
    <td class="col1">
      Cool Shirt
    </td>
    <td class="col2">
      Alien Poster
    </td>
    <td class="col3">
      Batman Poster
    </td>
    <td class="col4">
      Bullseye Shirt
    </td>
    <td class="col5">
      Another Classic Vinyl
    </td>
    <td class="col6">
      Awesome Jeans
    </td>
  </tr>
</table>

Table row parameters:

  • cols: {% tablerow product in collection.products cols:2 %}
  • limit: {% tablerow product in collection.products limit: 2 %}
  • offset: {% tablerow product in collection.products offset: 2 %}

Variables

You can initialize Liquid variables using the assign (creates a new variable) or capture (captures string inside of opening and closing tags and assigns it to a variable) tags.

Increment


{% increment my_counter %}
{% increment my_counter %}
{% increment my_counter %}

OUTPUT:
0
1
2

Decrement


{% decrement variable %}
{% decrement variable %}
{% decrement variable %}

OUTPUT:
-1
-2
-3

</body> </html>

The front matter for each of the pages must contain:

Setup Index page like this:

My home page just has a title and a link to the book collection page that I want to work on first for my site.


---
layout: default
title: The Essentialist Developer
description: Essentialism is a disciplined, systematic approach for determining where your highest point of contribution lies, so that you can make it a reality.
image: the-essentialist-dev.png
---

<h1>The essentialist developer, part one</h1>

<p><a href="books.html">Inspiring Books</a></p>

Create books.html with following markup:


---
layout: default
title: Inspiring books
---

<h1>The essentialist developer, part one</h1>
<p>Whenever you read a book, experiment with the ideas in them. They have the power to change your life, if you take action.</p>

<section>
  <div>Tech</div>
  <div>Design</div>
  <div>Life-Strategies</div>
  <div>Tools</div>
</section>

<article>
  <h1>The Pragmatic Programmer</h1>
  <p>David Thomas and Andrew Hunt</p>
  <a href="#">S</a>
  <img src="#" alt="The Pragmatic Programmer Book Cover">
  <p><q>Kaizen</q> is a Japanese term that captures the concept of continuously making many small improvements.</p>
  <a href="#">Read Notes</a>
</article>

I already have a design mocked up for my book collection page. So I just wrote the raw HTML to make this happen, no classes, and the data for the only book on the page is hard-coded.

There are a few things I'm going to need to do to the book page to make it work. I need a CSS reset and some decent styles, but that's secondary to the behaviour right now, so that's what I'll focus on first. I'm going to start by creating a book collection in Jekyll, so that the book cards will be generated from that. Then I'll turn each of the filters into links, and make it so that only books that contain the selected category (books can be in more than one category) will be displayed.

Before I do that, I'm going to make a quick READme file, containing the API information I caught for my boilerplate HTML. I want to turn that into documentation at some point, so that there are a list of tutorials for adding new pages and collections to my site. But for now, a README.md is enough.

The first step is to add a 'books' collection to my site, by creating a '_config.yml' file in the root directory of my site, and then adding the following:


collections:
  books:
    output: true
    permalink: /books/:path

Then I created a _books directory. Inside the _books directory, I created a file for my book the-pragmatic-programmer.html with the following code inside:


---
title: The Pragmatic Programmer
authors: David Thomas and Andrew Hunt
quote: '"Kaizen" is a Japanese term that captures the concept of continuously making many small improvements.'
img_url: /assets/images/book-covers/the-pragmatic-programmer.jpg
category: Tech
---
<h1>The essentialist developer, part one<h1>

Then I went back onto my books.html page and added permalink: /books/ to the front matter, which meant I had to change the 'books.html' link in the index page to 'books'. Then I replaced the hard-coded book information with the following:



  <article>
    <h1>The Pragmatic Programmer</h1>
    <p>David Thomas and Andrew Hunt</p>
    <a class="book_card__share-twitter" href="https://twitter.com/intent/tweet?text=[What is your favourite takeaway from The Pragmatic Programmer]&url=https://becca9941.github.io/books/prag-prog&via=becca9941&related=becca9941" rel="nofollow" target="_blank" title="Share on Twitter">Share</a>
    <img src="/assets/images/book-covers/" alt="The Pragmatic Programmer Book Cover">
    <p>"Kaizen" is a Japanese term that captures the concept of continuously making many small improvements.</p>
    <a href="/books/prag-prog">Read Notes</a>
  </article>

  <article>
    <h1>The Pragmatic Programmer</h1>
    <p>David Thomas and Andrew Hunt</p>
    <a class="book_card__share-twitter" href="https://twitter.com/intent/tweet?text=[What is your favourite takeaway from The Pragmatic Programmer]&url=https://becca9941.github.io/books/the-pragmatic-programmer&via=becca9941&related=becca9941" rel="nofollow" target="_blank" title="Share on Twitter">Share</a>
    <img src="/assets/images/book-covers/" alt="The Pragmatic Programmer Book Cover">
    <p>"Kaizen" is a Japanese term that captures the concept of continuously making many small improvements.</p>
    <a href="/books/the-pragmatic-programmer">Read Notes</a>
  </article>


Okay, so we know that we can display books by adding a new book with the following information to the book collection folder:

At the moment the book cover is huge. Once I have resized the card to fit on mobile screens during the restyling phase, I'll resize the image itself to the same dimensions because there will never be a need for it to be that big.

The next thing I want to do is make sure that the category filter list only shows categories that are actually assigned to books. In the 'books.html' page, I swapped out the individual category divs with the following:


  
    <div>Tech</div>
  
    <div>Tech</div>
  

The next step is to filter the books by the active filter chips. Will save that for the next post! :)