Posted on 2018-02-23. blog meta
This is it! After some thoughts, I decided it was time for me to finally open a tech blog, so that my article ideas may become concrete. After a couple of days hacking to produce something I am not ashamed of showing to the public, it is now online, ready to receive some content. I really do hope I will take the time to fill it, and also hope that the content will be worth reading.
To inaugurate this blog, let’s start with a post that describes what technologies I chose to host this content.
What about the content?
Posts will be about technical thought I have, open-source projects I am working on, proofs of concept, and probably many other matters. As an open-source enthusiast, I chose an open license for the content (namely the CC-BY-SA 4.0, see the badge on the left) and you will be able to download the source of every article by clicking on the View source link on the upper right corner of each post.
This is also an opportunity for me to try my idea of a blog where posts are written using the literate programming paradigm from time to time. This is not the case for this post, but probably more to come on that matter…
Even though I am not entirely convinced for now, comments are available on posts. This is an experiment of mine, and I may choose to disable them either entirely or for some selected posts if I get to much spamming and trolling. I know, for that to happen some visibility is necessary, but who knows?
This blog is also entirely self-hosted, there is no call to external CDN or analytics server, you are not tracked by some social network badges, all requests made on this blog pages target my personal domain name. Of course, should you notice this is not the case, constructive feedback is always welcome in the comments to improve that. Comments are also hosted on my own server, more on that in the next section. My goal is to share knowledge without selling data of my visitors to some company.
That being said, let’s dive into technical stuffs.
Technical details
Starting a tech blog was also an opportunity for me to discover new technologies or to update my lacky knowledge on other ones.
The engine
In the past I have been using Jekyll and TiddlyWiki for similar blogging purpose, but they both have caveats I wanted to avoid here.
Jekyll is well-established, has a big community, a lot of plugins, etc, but I always get frustrated when using it because my needs relentlessly end up not being how Jekyll wants my site to be done. I found it quite a hassle to extend Jekyll so that new processing steps are performed when compiling my site.
TiddlyWiki is really interesting when I need to build a website that resemble a mind map, or when each part of the content is intrinsically tightly linked to other parts. Of course, TiddlyWiki is a really nice quine, well-architectured, quite easy to hack and extend, but this is not what I need here. A simple blog does not need all the flexibilty TiddlyWiki offers.
Adding to that the fact that I wanted to take a travel outside my comfort zone, I decided to go for nanoc. This static site generator has several advantages and an interesting approach:
- it is written in ruby, and I like that language for scripting;
- it is simple at its core, does not presume what you want to do and how you should build your website;
- it has a good documentation and a simple interface;
- it comes with a handful of filters and small helpers and makes it really easy to add new ones;
- its concept of compilation, layouting, and routing rules is what I needed;
- deploying the blog is really easy.
Of course this list is not exhaustive, nor is it objective.
Customizations
The fact that blogging features are not part of the core of nanoc is great because you can do it your way. Of course this comes at a cost: you must hack to tailor nanoc to your needs. But, nanoc being designed to be hacked, this is done easily. The main features I wanted to have for this blog are:
- posts organized by date in the result, but not in the sources (I do not want to rename or move my source file if I change the publish date);
- possibility to download the source of each post (will comes in handy for posts written in literate programming);
- concept of sagas, where several posts are different episodes in the saga, and with a ToC to navigate between the episodes;
- the possibility to process different input format at different stages of the compilation.
The first point is achieved by the routing rules of nanoc.
route '/posts/*' do
date_path = item[:created_at].strftime("%Y/%m/%d")
"/posts/#{date_path}/#{File.basename(item.identifier.without_ext)}/index.html"
end
My posts live in a directory named posts
, and the frontmatter contains a created_at
metadata that contains the publish date (the name is the one required by the Blogging
helper, even though I would have preferred a published_on
metadata). The above routing rules makes it possible to create a target directory structure with the creation date of each post and takes the source file name has post identifier. If I decide to change the publication date, all I have to do is to modify the metadata accordingly, not move or rename the post source file.
For what concerns the possibility to download a post source code, I am taking advantage of the preprocessing code blocks of nanoc rules.
preprocess do
# create raw version of the articles
articles.each do |article|
date_path = article[:created_at].strftime("%Y/%m/%d")
raw_id = "/raw/#{date_path}/#{File.basename(article.identifier)}"
article.attributes[:raw_id] = raw_id
@items.create(article.raw_content, {}, raw_id)
end
end
For each article a new nanoc item is created, which lives in the raw
directory. Creating a new item in the preprocessing phase, makes it possible to use the LinkTo
helper to create links to the source in the article, without having to bother how this will be mangled by nanoc.
For my sagas, I wrote a small helper called Sagafyer
.
module Sagafyer
def saga_toc(article)
if article[:saga] and article[:episode]
saga = article[:saga]
episode = article[:episode].to_i
episodes = articles.keep_if { |a| a[:saga] == saga }.sort_by! { |a| a[:episode].to_i }
if episodes.length > 1 then
toc = episodes.each_with_index.map do |ep,i|
"<li>Episode #{i+1}: #{link_to_unless_current(ep[:title], ep)}</li>"
end
<<-EOS
<div class="siimple-box">
<div class="siimple-box-detail">
<h4 class="siimple-h4">This post is part of the saga <em>#{saga}</em></h4>
<ul>
#{toc.join("\n")}
</ul>
</div>
</div>
EOS
end
end
end
end
If a post has a saga
and an episode
metadata, then it will take part to a saga. If several posts are part of the same saga, then a ToC is generated at the end of each post to navigate between the episodes.
Finally, for the different processors, I did not implement any yet, but this is to come, to handle new input formats. Nanoc makes it easy to add them by implementing new filters that are then applied in the compilation rules.
More helpers are probably to come, depending on my needs in new posts.
The comments
So, I decided I would have a blog with comments. But I didn’t want to depend on some external service like the popular Disqus for that (remember, privacy matters).
The comments on this blog are self-hosted and use isso as comment engine. It is simple to install, easy to integrated in your page, and looks flexible enough for what I need. Markdown is supported, should you want to format your comments properly, or add links to them.
For the moment, they are not monitored, but this is something that could come in the future.
The style
Let’s say it right away: I suck at CSS! Nevertheless, I want a blog that looks clean and beautiful. And I discovered siimple, a stylesheet that is simple to use (what a surprise, didn’t see that coming from the name) and renders quite nicely.
I tweaked it a little to use the open source overpass font instead of depending on Google Fonts, and I added the open iconic to replace standard social media badges.
What now?
So, this is where we are standing. Of course, there is still work to do to fix problems here and there, especially in the CSS, but this is a good start. Some features are still missing and will come in a near future:
- ToC generation for posts;
- saga wrap-up page with summary;
- a release announcement page for my open-source projects;
- an atom feed;
- more content!
This will come in good time, just keep an eye on this blog.