Upgrading the Blog
As mentioned in my post about how I set up this blog, there still seemed like there might be some necessary features to be added. And as I experiment and write up some posts in advance, I can see that at least a couple of those features need to be there before the new year hits. So, this is that story.
Pagination
As I add pages for future release, it became obvious that pagination isnât a default part of Jekyll and, if I imagine two posts per week (Iâll post details on my plans next week), the blog is likely to become unusable after a few months.
A quick web search turned up Jekyllâs own page on the subject. I followed the instructions, though hit a couple of small snags:
- The documentation isnât quite clear that the blogâs existing
index.markdown
needs to be removed and replaced with anindex.html
file in Jekyllâs root folder. From there, the sample page makes a good start that I was able to adapt with the changes I had already made for my_layouts/home.html
. Except⌠- Unlike
layouts/home.html
andindex.markdown
, theindex.html
frontmatter requires atitle
. Without it, Jekyll picks another page in the root, specifically my code of conduct, for some reason. It took a surprisingly long time to figure what was going on, there. - It looks like the pagination gem doesnât understand how to combine the
baseurl
andpaginate_path
options. The link second page link pointed to/blog/page2
, but the page was generated at/blog/blog/page2
. - Because the post pages are pre-generated, they showed up in my header. I needed to add
and my_page.title != 'Posts'
to the_includes/header.html
line that decides whether to render a link to the page.
Obviously, most of these can be worked around, but that third item was a huge problem that didnât appear to have any resolution. So, I started to investigate the successor project.
I updated the gem and then stumbled around, trying to find the configuration documentation. It claims that itâs compatible with the original version, but actually requires a completely different configuration. Eventually, I found the directions and was able to quickly remove the old configuration and replace it withâŚ
pagination:
enabled: true
per_page: 8
permalink: 'page/:num/'
sort_reverse: true;
It seems silly to require enabling it as part of the configuration, and sillier still to make reverse-chronological sorting an option when itâs obviously how every blog works, but sure. Oh, also silly (keep scrolling down the documentation page), the index file needsâŚ
pagination:
enabled: true
âŚadded to the index.html
frontmatter, because we havenât turned this feature on nearly enough times, I guess.
If you scroll even further down the page, you can see the warning stating that backward-compatibility was dropped in January 2018, explaining that mystery.
Just one problem, this time, despite the goofy configuration. Once again, the permalink
setting doesnât play well with baseurl
. In this case, though, I just added /blog
to the start of the paging URLs in the index. Thereâs probably a better way of handling this, but it does the job.
Tagging
Jekyll has some gems to handle tags, but on the chance that I might eventually want to use GitHub Pages to host the blog, it looks like the state of the art is Long Qianâs approach.
It took about five minutes to churn through the entire thing, though there are a few minor glitches.
First, the instructions arenât using siteurl
, which means tweaking some of the tag-page URLs to make this work.
Second, someone needs to keep the tag pages up to date as posts are added and modified. Fortunately, I already have a script I use to rebuild and deploy the blog to my server, so itâs easy enough to add something likeâŚ
rm tag/*.md
for tag in $(grep '^tags:' _posts/* | cut -f2- -d'[' | cut -f1 -d']' | tr -d ' ' | tr ',' '\n' | sort -u)
do
cat > "tag/${tag}.md" <<EOF
---
layout: tagpage
title: "Tag: ${tag}"
tag: ${tag}
---
EOF
done
Now, every time I rebuild the blog, the tags will also get rebuilt. If youâre curious and arenât familiar enough with the Linux command line to work it out on sight, the above code removes the existing tag files and (a) checks all posts for tags, (bâe) sets them up one per line, and then (f) makes sure that each only appears once. Then, for each unique tag, I create a tag file named after the tag with a layout, title, and tag name.
Third is another mild frustration: Since the tag files are not posts, Jekyllâs default wants to include them in the blog headerâs links. I filter them out the same way I filter the pagination files, above.
Because tags are represented in Jekyll by non-post pages, itâs also easy to iterate through the pages and link to each tag page in hopes of helping readers find posts of interest. That codeâŚit turns out that Liquid templates are processed before converting from Markdown, so I canât show it in full. So, the following replaces the open braces ({
) with open parentheses ((
) to not just dump the tags into this page.
(%- assign default_paths = site.pages | map: "path" -%}
(%- assign page_paths = site.header_pages | default: default_paths -%}
(%- for path in page_paths -%}
(%- assign my_page = site.pages | where: "path", path | first -%}
(%- if my_page.title -%}
(%- if my_page.title -%}
(%- assign title = my_page.title | split: " " -%}
(%- endif -%}
(%- if title[0] == 'Tag:' -%}
<div>
<a href="/blog/tag/(( title[1] }}">
<i class="fa fa-tag"></i>
(( title[1] }}
</a>
</div>
(%- endif -%}
(%- endif -%}
(%- endfor -%}
And thatâs tagging taken care of.
Search
The tags will probably go a long way towards making posts discoverable, but as the number of pages increases, Iâm going to want the ability to search for a page. I mean, I donât need a search box, because I can just search the source files to find what I want. But someone might need to search it who doesnât want to go to that kind of trouble.
Fortunately, Sharath at Webjeda found a reasonable solution. I needed to play with URL paths again and tweak the Liquid template to prevent tab characters from fouling up the JSON, for some reason, but I now have a working search page that works as advertised!
Putting the search bar on the header might make more sense, at some point, but loading up all the text of the blog onto every page honestly seems like a performance nightmare, so I probably wonât bother until I see complaints about the separate search page.
In the future, I may want to update the search code to strip out diacritical marks, so readers donât need to worry about it. But for now, there are few enough non-Latin characters for me to worry about it just yet. Unfortunately, it doesnât look like itâs possible to do that using Liquidâs templates that generate the JSON, so itâll need to happen in the JavaScript code.
The Winners, Take Two
I still have a couple of tasks ahead of me for this to seem to be at one-hundred percent:
- Update search to ignore diacritical marks.
- I would like Hashover to use Libravatar instead of Gravatar; while I trust Automattic more than I trust Disqus, itâs still relying on a company that might start selling data.
- The jury is still out on anonymous comments.
However, for now, the tools that work, in addition to Jekyll and Hashover, are:
- Paging with Jekyll-Paginate-v2
- Long Qianâs custom tag pages, with a script to generate them
- Christian Feiâs Simple Jekyll Search on Sharathâs advice.
And Iâve taken a quick look at Libravatarâs API and it seems entirely plausible if Hashoverâs architecture will allow another service.
So, with that, I think the blog is pretty much ready for the new year. What a nice Christmas present for myself! đ
Credits: Untitled header photograph from PxHere, made available under the CC0 1.0 Universal Public Domain Dedication.
No webmentions were found.
By commenting, you agree to follow the blog's Code of Conduct and that your comment is released under the same license as the rest of the blog. Or do you not like comments sections? Continue the conversation in the #entropy-arbitrage chatroom on Matrix…
Tags: blog meta technology