30 Oct 2018

Hacktoberfest - Week Four

Hacktoberfest week four! In keeping with the theme I set last week I continued to improve open source project documentation as part of Hacktoberfest. This week I returned to dplesca/purehugo, the theme I use for this blog, to help out with improving some areas of the documentation I noticed could use a bit of polish during my first contribution to the project during Hacktoberfest week two.

In dplesca/purehugo#28 I rephrased the section of the README.md that deals with code syntax highlighting on generated blogs. As I mention in the issue, it seems as though the original author simply missed a word when writing the section:

All you need to do is to let rainbow.js the language of the highlighted code […]

which should instead read:

All you need to do is to let rainbow.js know the language of the highlighted code […]

The simple fix in this case would be to add the missing word. However, since I knew I would be editing this part of the document anyways, I decided to take a bit more time and rephrase the existing wording to simplify the instructions and use more specific language to instruct new users what they need to do to get the highlighting library to pick up the desired language. I also added a full example of how to apply Go syntax to a code block using Markdown, as I find seeing complete code samples or full examples in documentation to be very helpful when I’m learning a new tool or framework, and serve as quick reminders if I’m returning to a tool or framework I haven’t used recently to get me back on track.

This week turned into a twofer because while I was working on dplesca/purehugo#28 I noticed a small spelling error elsewhere in the README.md file and submitted dplesca/purehugo#27 to correct a word in one of the document headings. I only noticed the spelling mistake as I had just set up proper spell checking in Visual Studio Code using Spell Right by Bartosz Antosik to warn me about typos and other spelling errors. I had been under the impression that VS Code shipped with spell checking by default but this does not seem to be the case. Further, the VS Code spellchecking addon I found published by Microsoft is marked as deprecated and suggests finding an alternate addon. Correcting minor typos in documentation is small potatoes compared to some other Hacktoberfest contributions, but they are important changes that affect readability, comprehension, and the flow of the document(s) in which they occur.

The end of Hacktoberfest is almost upon us, and I have one last post to share about my final contribution this month. Look forward to a piece about my first major contribution to a Rust project!

15 Oct 2018

Hacktoberfest - Week Two

Hacktoberfest week two! Week one was all about getting into the groove of Hacktoberfest, making a small change to contribute, and finding out about other awesome projects in open source and my area of interest.

My contribution for this week had a bit more self-interest involved; I contributed a change to dplesca/purehugo, the Hugo blog theme I use for this blog, to normalize URLs that use Hugo’s .Site.BaseURL variable.

The Problem

Using the dplesca/purehugo theme, I was noticing that many links to other parts of the site - that is, links that were not external links to e.g. GitHub or Twitter - contained multiple slashes after the site root. Modern web browsers are really good at dealing with partially-malformed URLs so there was no functional problem with any of the links as the browser’s URL parser took over and cleaned them up into a value it could resolve, but it would still be better if the URLs were correctly formatted when Hugo generates the static site content.

The malformed URLs looked something like this:

<a class="pure-button" href="http://localhost:1313//index.xml">[...]</a>
<a class="post-category post-category-open source" href="http://localhost:1313//categories/open-source">open source</a>

Delving into the template code revealed how dplesca/purehugo was generating the URLs:

<a class="pure-button" href="{{ .Site.BaseURL }}/index.xml">[...]</a>
<a class="post-category post-category-{{ . }}" href="{{ $baseUrl }}/categories/{{ . | urlize }}">{{ . }}</a>

The template string used .Site.BaseURL and appended a slash before the next URL fragment. Since this results in a double slash in the generated output, I presume but have not confirmed that .Site.BaseURL always ends in a trailing slash that needs to be taken into consideration when generating URLs relative the the site’s root.

The Solution

In a similar way to how we join file paths in NodeJS with path.join(), we almost never want to be responsible for building URL paths ourselves. Luckily, Hugo provides many built-in helper functions that cover a whole range of use cases, including the one I decided to use to normalize URL paths throughout dplesca/purehugo: absURL

From the Hugo documentation, absURL

Creates an absolute URL based on the configured baseURL.

where baseURL is the hostname (and path) to the root of the site which is set as part of Hugo’s site configuration.

This function was a perfect solution in most of the places where static files need to be linked and served to the client, such as JavaScript or CSS content. In those cases it was a simple matter of removing .Site.BaseURL and the subsequent concatenation and replace it with a call to the absURL function, like so:

<a class="pure-button" href='{{ "index.xml" | absURL }}'>[...]</a>

Normalizing the post category links turned out to be a bit more complicated than this simple substitution because these links needed to include more URL fragments to create the complete path. In order to correctly concatenate and then normalize these URLs, I turned to another of Hugo’s built-in functions: printf.

Hugo’s templating system is built almost entirely on top of Go’s built-in template package, which makes things very familiar if you have worked with Go templates before. It also means that Hugo can expose a lot of Go functions as Hugo functions available inside templates. In this case, Hugo’s printf function exposes Go’s fmt.Sprintf function which works much like printf in C.

This is the solution I came up with for building the more complicated post category link URLs while still being able to normalize the resulting URL using absURL:

<a class="post-category post-category-{{ . }}" href='{{ ( printf "categories/%s" . ) | absURL }}'>{{ . }}</a>

Unlike in NodeJS, in this case it’s safe to do a simple string concatenation of categories/<category-name> because unlike with file systems, the fragment separator in URLs is always the / character.

To be Continued

I am very thankful to purehugo’s author, @dplesca, for responding so quickly to my pull request with this change and for merging the pull request within a few hours of my submission. While working on this change I noticed a few other areas where I think dplesca/purehugo could be improved, and I’m looking forward to working on it more as I continue using it to generate my blog and host my site content.

Hacktoberfest continues on, and I need to start thinking about my next contribution. My school is on a break starting next week, so I’m hoping to find the time to dig into something a bit larger and more challenging based on the projects I’ve seen so far or had recommended to me by classmates.