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