2020-09-27-switching-to-own-ssg.md (9327B) - raw

      1 <!-- title: Switching to my own static site generator -->
      2 <!-- slug: switching-to-own-ssg -->
      3 <!-- categories: FOSS, Personal domain, Projects -->
      4 <!-- date: 2020-09-27T16:27:00Z -->
      6 Since the start of this website (its first anniversary was a couple of weeks
      7 ago!) until recently, I have been using the static site generator [Hugo][h].
      8 Static site generators are very useful when building relatively complex static
      9 websites, and Hugo has served me well. I have also used [Lektor][l] and
     10 [Jekyll][j] before for other projects, but for a site with a blog, I like Hugo
     11 the most. However, with time, some issues have arisen with Hugo, and I finally
     12 decided to change my site's generator.
     14 ## Issues with Hugo
     16 If you build your website with a static site generator, it will probably be the
     17 most critical dependency of your site. Of course, it's a dependency I'm fine
     18 with as it makes things much easier (dealing with Markdown content, categories,
     19 web feeds...), but if something goes wrong, the site won't render as you want.
     20 Hugo in particular is a very big project and I don't feel like jumping into the
     21 source code every time I have an issue with the program (especially since I've
     22 never used Go, and I don't want to spend hours for minor annoyances). Although
     23 Hugo works wonderfully, I have encountered moments where it has acted
     24 unpredictably, and documentation doesn't help most of the time.
     26 On top of that, although it works perfectly well (and it is one of the most
     27 popular SSGs), it is on a beta stage and the developers have made
     28 backward-incompatible changes without warning in the past. The change I have in
     29 mind was clearly stated on the release page, but I normally let my package
     30 manager handle the updates, and I want my computer to keep working correctly (or
     31 throw big red warnings all over the place). In this case, HTML inside Markdown
     32 files stopped rendering, and I only found out coincidentally a couple of weeks
     33 later as the web feed was not valid anymore. From that moment on, I started
     34 checking the release notes for every update (which are frequent, about once a
     35 week), but it was an annoying routine.
     37 I understand that the program is in beta and it was on me to check for breaking
     38 changes, but to be fair, Hugo is marketed as a fully functional program (as if
     39 it wasn't on a beta stage) on the official website. Considering my last issue,
     40 this was concerning and ended up creating uncertainty on the stability of Hugo
     41 and the transparency of the developers, so I decided to change my site
     42 generator.
     44 ## Taking the leap
     46 I wanted to move to something lightweight that could still be useful in a few
     47 years' time, ideally a program that was easy to understand and maintain. The
     48 problem was that I had some very specific needs that small programs didn't
     49 fulfill, leaving only big programs as an option (which I didn't want to use). I
     50 thought of the possibility of creating my own site generator, but it looked like
     51 a large task I didn't want to spend my time on. Hugo was working fine, and
     52 although I kept looking up other SSGs when I discovered them, I stopped actively
     53 looking for alternatives or thinking about designing my own.
     55 Until the night of the 5th of September, when I came across [makesite.py][ms].
     56 This project was just perfect, and I couldn't resist. Let me show you an extract
     57 of the README:
     59 > Have you used a popular static site generator like Jekyll to generate your
     60 > blog?
     62 Yes...
     64 > I have too. It is simple and great. But then did you yearn to use something
     65 > even simpler to generate your blog? Do you like Python? Perhaps the thought of
     66 > writing your own static site generator crossed your mind but you thought it
     67 > would be too much work?
     69 Yes, yes, and definitely yes!
     71 > If you answered "yes" to these questions, then this project is for you.
     73 Nice! That night I read the README and the source code (which is shorter than
     74 the README). The program is very simple and a lot of the basic functionality I
     75 needed out of a static site generator was already there. On top of that, it
     76 didn't use any non-standard Python library except for the Markdown parser. I
     77 really liked the project and I thought it could be the foundation of my personal
     78 static site generator.
     80 It was. The next morning, I started coding to make it usable for my website. I
     81 had to implement many new features, but with Python it was [easy and fun][xkcd].
     82 After two days of working on it, I finally released my site using a personal
     83 fork of makesite.py, [gensite.py][gs]!
     85 ## The new benefits
     87 So, why change the SSG if Hugo was working fine? As I said, I've had my issues
     88 with Hugo, and I don't want to be forced to leave my static site generator if
     89 more arise in the future. I don't know if I'll be able to switch SSGs when (and
     90 if) the time comes, and now I have the time and motivation needed to do it, so I
     91 decided to take the chance while it was there. On top of that, *gensite.py* is
     92 not only my "way out of Hugo", it is a program that has many features that could
     93 have made me do the change without having any troubles with the last SSG.
     95 First of all, the program is very small, it's only about 270 lines of code and
     96 it's written in Python. That makes it very easy for me to read and understand
     97 the whole program very quickly, even if I have completely forgotten everything
     98 about it. Obviously, this doesn't count the lines of code of the libraries it
     99 depends on, but those are all standard libraries and the functions are easy to
    100 understand, except for the Markdown parser, but if that ever gives me any
    101 trouble I can change it without much effort.
    103 Since *gensite.py* is made exclusively for my website, it is more closely tied
    104 to the rest of my site. For example, it doesn't have a complex template engine,
    105 instead, templates only process the following two snippets:
    107 - `{{ var }}`: substitutes the string for the value of variable `var`.
    108 - `{{ _if var }}text{{ _fi }}`: will render the text `text` if variable `var` is
    109   defined. You can't have an `_if` inside another.
    111 If I need anything more complex, I will use Python to create the text and pass
    112 it as a variable when rendering the template. I prefer this approach as it is a
    113 lot nicer to implement those features in Python than it is with a template
    114 engine. For some pages—for example, the archive—Python does some more heavy
    115 lifting and creates part of the HTML. This can sound weird in comparison with
    116 other static site generators, where HTML is only dealt with in the template
    117 files, but it makes things simpler, and I no longer need hacky templates to
    118 create certain outputs.
    120 Moreover, I like the file structure a lot better (I designed it!), and if I ever
    121 want to change it, it shouldn't take long to do so. Similarly, any other design
    122 options are exactly as I want them to be, since it is me who decided them. In
    123 case it is not clear: everything works exactly as I want it to!
    125 Finally, it's a project that doesn't move too fast. One of the problems with
    126 websites is that links are easily broken: entities change their backend, run out
    127 of money, mess up an update, etc. and let their links break. Right now, I am
    128 pretty dedicated to my website, and if my SSG broke something on my website, I
    129 would spend the time to fix it, but I can't ensure I'll do the same in two or
    130 five years (and I don't want to break any links, even on the long term, but
    131 that's a post for another day). Unless something happens with Python,
    132 *gensite.py* will work and so will the generation of my website. There won't be
    133 any updates that break some random page or that change a certain behaviour[^u].
    134 I hope *gensite.py* can stand the test of time, but we'll see...
    136 [^u]: Also, whenever I make changes to *gensite.py*, I can run `diff -r` to
    137   check for differences for the outputs before and after the update. With Hugo,
    138   many files changed without explanation (although it was mostly style choices,
    139   it made it hard to see the real changes in content between updates).
    141 ## Final comments
    143 Forking *makesite.py* and setting up everything I needed for my website was very
    144 fun, but it is surely a process that not everyone will enjoy. I have lately been
    145 leaning towards software that is a simple as possible, software that is easy to
    146 understand and change if needed. It takes time to set up, but once it's working,
    147 you can forget about it (and if you need to make changes, they are quickly
    148 implemented) and you will have software that works exactly as you want it to. I
    149 am very meticulous about this website and try to have good control over
    150 everything that happens during the website's generation, and I couldn't be
    151 happier with *gensite.py*.
    153 On another note, I don't want to end this post without saying that Hugo has been
    154 a great static site generator, and I'd recommend it to anyone who wants to have
    155 a blog on a static website. In a new update with breaking changes, they did
    156 throw errors if the old feature was used, so maybe my experience wouldn't happen
    157 again. Just remember, it's still in beta.
    160 [h]: <https://gohugo.io> "Hugo"
    161 [l]: <https://www.getlektor.com> "Lektor"
    162 [j]: <https://jekyllrb.com> "Jekyll"
    163 [ms]: <https://github.com/sunainapai/makesite> "makesite.py — GitHub"
    164 [xkcd]: <https://xkcd.com/353/> "Python — xkcd"
    165 [gs]: <https://git.oscarbenedito.com/oscarbenedito.com/file/gensite.py.html> "gensite.py — git.oscarbenedito.com"