Blog post: Experimenting with GitHub Pages and JavaScript and Putting Everything to Use
Tags: github, javascript, learning
Published: 2020-01-29 19:02:56

---
title: Blog post: Experimenting with GitHub Pages and JavaScript and Putting Everything to Use
published: true
description: Getting more out of GitHub Pages
tags: github, javascript, learning
---
A long time ago I blogged about [GitHub Pages](https://lastmover.wordpress.com/2017/01/01/github-pages/) and getting started with setting up a webpage.

The static webpages are nice and they can help you make your project or documentation look good, but for a long time I wanted to take this a bit further.

First I wrote two prototypes:

- [One](https://github.com/jonasbn/github-pages-javascript-prototype) extending a GitHub Pages set up with JavaScript serving data from  a local resource
- [Another one](https://github.com/jonasbn/github-pages-javascript-prototype-external-data) serving data from a remote resource

Both worked fine, but I wanted to extend this beyond the prototype stage. And I would LOVE to go crazy in a cool looking, super interactive solution, but I have to be honest:

- I am not an experienced frontend developer
- I am no web designer
- And am by no means there yet, with my web and JavaScript skills

I feel over [this nice article](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents
) on Mozilla Developer Network ([MDN][mdn]) and I got an idea, something I could, something pretty basic I could do with [my collection of "Today I Learned" notes][til]. I could add some JavaScript to make it more interesting.

But there was and still is a lot of hurdles to get over to get to something working, so lets start at the beginning. [GitHub Pages][github_pages] use [Jekyll][jekyll] which is a static site generator written in Ruby. You can add themes to make it stand out and [you can customize the layout](https://help.github.com/en/github/working-with-github-pages/adding-a-theme-to-your-github-pages-site-using-jekyll#customizing-your-themes-html-layout) using CSS (Sass) and by changing the HTML templates.

When wanting to play around with these themes what I have normally done was to clone the specific theme, like:

- [Cayman](https://github.com/pages-themes/cayman)
- [Architect](https://github.com/pages-themes/architect)

There a plenty of [other themes](https://github.com/pages-themes) to choose from and with customization, you are not stuck with the standard layout, which is a HUGE help if you like me, is not a web designer.

In the past I have made use of [GitHub Pages][github_pages] and [Jekyll][jekyll] for many of my projects and repositories, but mostly I have been in a situation where I had to commit, push and wait for me to see the changes applied - and this is not particularly gratifying. It can work for layout, but for coding, I must admit I would prefer something more coding environment like.

So when I started playing around extending the project with JavaScript, I would have to solve the problem on how to get feedback faster from my changes. I have previously used different hacks where I would render the relevant HTML and CSS in a browser based on files, but the changes where small and pretty basic. This did require some more and adoption of some new tools.

First, I need [Jekyll running locally on MacOS](https://jekyllrb.com/docs/installation/macos/) and I wanted to get in a situation where I could simply do (_lifted from: ["Jekyll: Quickstart"](https://jekyllrb.com/docs/)_):

```bash
$ bundle exec jekyll serve
$ open http://localhost:4000/
```

And then all the _editing_ so I could see the result of my work and get feedback, prior to commiting and pushing...

Luckily I was able to locate good resources from the GitHub help pages, guiding me to get this working:

- ["Creating a GitHub Pages site with Jekyll"](https://help.github.com/en/github/working-with-github-pages/creating-a-github-pages-site-with-jekyll)
- ["Testing your GitHub Pages site locally with Jekyll"](https://help.github.com/en/github/working-with-github-pages/testing-your-github-pages-site-locally-with-jekyll)

So this was basically the steps I took.

I am using `rbenv`, so I have a local Ruby installation for the project.

```bash
$ rbenv local 2.6.3
```

I created a `Gemfile`

```bash
$ cat Gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

# gemspec
gem "github-pages", group: :jekyll_plugins
```

I installed [Jekyll][jekyll] and `bundler`

```bash
$ gem install jekyll bundler
```

And now I can run the site locally.

```bash
$ bundle exec jekyll serve
```

Pointing my favorite browser to: `http://localhost:4000/`

Next up was getting my head around the actual problem.

When we have is a HTML rendered from a Markdown file. We can control the CSS and do some extent the HTML. But as you can see from the [HTML skeleton](https://github.com/jonasbn/til/blob/master/_layouts/default.html).

```html
    <div id="content-wrapper">
      <div class="inner clearfix">
        <section id="main-content">
          {{ content }}
        </section>
```

Our main content is simply wrapped, so we are not able to control the translation from Markdown and the handling of the HTML layout for this part. We can apply CSS and make it look different, but we cannot control the _data_ originating from the Markdown.

I searched for different approaches and with different words trying to find out how I could wrap a section indicating start and end of a part of the data and the closest I got was a jQuery solution, [`.wrapInner()`](https://api.jquery.com/wrapInner/).

Unable to find a construct with exactly the capabilities I needed I ended up using a combination of [`document.querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) and [`element.querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll).

Luckily I was able to identify all of the necessary elements relying on the `<h3>` tag.

```javascript
document.querySelectorAll('h3').forEach(element => {
    count_tils(element);
});
```

Feeding the selected elements to my counter function:

```javascript
function count_tils(element) {
    var sibling;

    if (sibling = element.nextElementSibling) {
        var list = sibling.querySelectorAll('li');
        if (list.length > 0) {
            var descriptor = 'tils';
            if (list.length == 1) {
                descriptor = 'til';
            }

            var text_content = element.textContent + ' (' + list.length + ' ' + descriptor + ')';
            element.textContent = text_content;

            total_tils += list.length;
        }
    }
}
```

I could select the `<li>` tags and sum them up. Do note the topmost line in the JavaScript file is:

```javascript
var total_tils = 0;
```

As you can see the elements are added to the existing header (`<h3>`), by concatenating the count and a helpful string.

Now that I have the count I decided to do some more and I added it to the sidebar, which was carrying some text about the content on the page. This is together with a count of the categories,

The element for the sidebar was created using [`createElement`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) and added using `appendChild`, which I found out how to do from [a StackOverflow post](https://stackoverflow.com/questions/21422337/append-element-as-sibling-after-element).

```javascript
var category_count = 0;

const count = document.createElement('p');
count.textContent = 'A collection of ' + total_tils + ' tils in total, split on ' + category_count + ' categories';

var sidebar = document.getElementById('sidebar');
sidebar.appendChild(count);
```

The implementation can be seen at: [http://jonasbn.github.io/til/][til] and the JavaScript file, from where all of the above snippets come is available [here](https://github.com/jonasbn/til/blob/master/assets/javascript.js).

It is quite a learning curve getting your head around all of the APIs, but as soon as you discover something and are able to add it to you tool box you can move on to new problems. The toughest issue is actually the nagging feeling whether you are using the right API or something more _right_ is out there. [The Mozilla Developer Network (MDN)](mdn) is awesome as a resource, check it ouf if you are not familiar with it.

This concludes this post. If ANYBODY has any tips on how to approach this using web APIs I am very open to getting some more insights. Suggestions on how to improve the implementation made for [my TIL collection][til] are also MOST welcome, I always enjoy a good challenge and appreciate a pull request.

[til]: http://jonasbn.github.io/til/
[jekyll]: https://jekyllrb.com/
[github_pages]: https://pages.github.com/
[mdn]: https://developer.mozilla.org/en-US/