About this site

This site was created with GitHub Pages. In the process of learning about GitHub Pages, we decided to also document what we learned. The GitHub Pages approach leverages Jekyll. We also have sister site to this one where we build documentation with a different technology. That site is: travelmarx.github.io/scrapbook101core/.

Initial steps

We started out simply by creating this repository and editing using the GitHub user interface in a browser. We were able to set up the initial skeleton of the site with a few pages in under an hour.

We decided on the approach of using a folder named docs located in the master branch. See the GitHub Pages docs for other choices. After seeing that we could choose a theme in our repository setting, we choose a theme and build our docs. We immediately got a decent looking site right-out-of-the-box. Behind the scenes, GitHub Pages takes what you have checked in and automatically generates your web site from any HTML or markdown files you have in the document root.

So far so good, but we wondered about how we could have a table of contents (TOC) show up in the left frame of our rendered site. This led us to reading about GitHub Pages and Jekyll. Jekyll is what turns markdown files into HTML. We took the following steps:

Our table of contents file, toc.yaml, looks like this:

toc:
  - title: Introduction
    url: index
  - title: Get Started
    url: get-started
    sections:
      - title: Run local
        heading: run-local
      - title: Run live
        heading: run-live
  ...

The code to read the toc.yaml appears in the _layouts\default.html file and is logically this:

for itemLevel1 in site.data.toc.toc
    link = itemLevel1.url, text = itemLevel1.title
        for itemLevel2 in itemLevel1.sections
            link = itemLevel1.url#itemLevel2.heading, text = itemLevel2.title
            for itemLevel3 in itemLevel2.sections
                link = itemLevel1.url#itemLevel3.heading, text = itemLevel3.title
            endfor
        endfor
endfor

After almost one hundred small commits with the GitHub user interface via a browser, it became obvious that the next step was to build the docs locally because the browser, even with multiple windows, was not a good solution for bulk writing and meaningful commits.

Running locally

Running our site locally, enables to

For more information about running Jekyll locally, see Setting up your GitHub Pages site locally with Jekyll. After following the help, our site wasn’t rendering correctly and we realized that while working only on-line (with the GitHub UI) our pages didn’t seem to need what’s called front matter, but locally it was needed for each page. A simple front matter looks like this:

---
layout: default
toc_entry: about-this-site
---

The next thing we realized was that we would need a Gemfile to describe Ruby dependencies (Jekyll is written in Ruby) and a .gitignore to avoid checking in local files we didn’t need saved, including the locally built site HTML files.

Here’s an overview of the key commands used in Git Bash to get going locally:

$ git init travelmarx
$ cd travelmarx
$ get clone https://github.com/travelmarx/scrapbook101.git

Create Gemfile base as suggested by the help page.

$ bundle install
$ cd docs
$ bundle exec jekyll serve

Notes:

Further tweaks

Here is a running of list of further tweaks to our document editing and setup process, presented in approximate order we implemented them.

Add Boostrap

After running this doc site for a few weeks, we wanted to add tabbed content using Bootstrap. This lead us discover that there is a GitHub Page theme with Bootstrap 4 startup site. However, instead of using this, we ended up injecting the necessary Bootstrap scripts into the _layouts\default.html.

At first we didn’t notice the difference between the local URL (e.g., http://localhost:4000/index) and the live site URL (https://travelmarx.github.io/scrapbook101/index). The difference of “scrapbook101” made relative document links work locally but not live. This SO post pointed the way that we could specify a baseurl parameter when starting Jekyll locally. We do two things:

Another way to do this is outlined in the Jekyll help for Project Page URL Structure.

Highlight TOC

To make it easier to see what page of the TOC is currently in view, we apply the active class to the current page TOC entry. The Jekyll instructions to do this are here. At first, we tried to use page.url variable but ran into problems with the index.md page in that the page variable returned just a /. Also, we saw that the page.url included file extensions (e.g., .html), and to match we’d have to remove that, which isn’t hard with the Liquid templating language syntax. In the end, we decided to add a variable to each page’s front matter called toc_entry and used it match the TOC name in the _data\toc.yaml file.

Simple Navigation

To implement a simple previous/next page control (top right corner of page), we also used the custom page variable toc_entry and add some logic to create the previous/next text and links. It helps to study up a little on the Liquid sytnax. We found the Jekyll page useful as well as the Shopify Liquid basics page. The basics of the code, which we fully admit may not be optimal, depend on assigning a variable, incrementing a counter, and using the index operation in the TOC arraw of pages.

{% assign prev_page = "" %}
{% assign prev_url = "" %}
{% assign next_page = "" %}
{% assign next_url = "" %}
{% assign num_toc_elem = site.data.toc.toc.size | minus: 1%}
{% assign my_counter = 0 %}

{% for itemLevel1 in site.data.toc.toc %}
    {% if itemLevel1.url == page.toc_entry %}
        {% if my_counter > 0 %}
          {% assign prev_page = last_page %}
          {% assign prev_url = last_url %}
        {% endif %}
        
        {% if my_counter != num_toc_elem  %}
            {% assign my_counter = my_counter | plus: 1 %}
            {% assign next_page = site.data.toc.toc[my_counter].title %}
            {% assign next_url = site.data.toc.toc[my_counter].url %}
        {% endif %}
        {% break %}
    {% endif %}

    {% assign last_page = itemLevel1.title %}
    {% assign last_url = itemLevel1.url %}
    {% assign my_counter = my_counter | plus: 1 %}

{% endfor %}

<div class="collapse navbar-collapse" id="navbarSupportedContent">
  <ul class="nav navbar-nav ml-auto">>
      {% if prev_page != "" %}
      {% assign prev_page = "« " | append: prev_page %}
      <li class="nav-item nudge">
            <a role="button" class="btn btn-outline-primary" href="{{prev_url}}">{{prev_page}}</a>
      </li>
      {% endif %}

      {% if next_page != "" %}
      {% assign next_page = next_page | append:  " »" %}
      <li class="nav-item">
          <a role="button" class="btn btn-outline-primary" href="{{next_url}}">{{next_page}}</a>
      </li>
      {% endif %}

  </ul>
</div>

Update Layout

We were inspired by the collapsible sidebar navigation examples on Bootstrapious and created a cross between what we had and what was suggested on Bootstrapious. The changes were made to the Jekyll Layouts page _layouts\default.html.