Going static

How I got to love statically generated websites.

Posted by Viviane on April 5, 2017

I first discovered static websites about two years ago and now I have 6 repos on my machine which are static sites with almost as many hosting situations and development processes. Let me tell you how I got there. First, for readers who do not have a clear idea of what I mean by static website, here is a general idea of how websites work.

Dynamic / static, some basics

All website work basically the same way. You type a url http://www.mywebsite.com/myfile.html and this is somehow directed to an actual physical machine (through DNS) to which you send a “request”, for example give me “myfile.html” (your browser makes the request for you, using the language of http). Your machine is called the client and the distant one where the website is hosted is called the server. The way the server handles this request then depends on what kind of website you are visiting.

If it’s a static website, then the server role is only to check if the file exists and give it to you. On the other hand, if it’s a dynamic website, there is a program running on the server side that looks at your request and generates the html content to be sent on the fly. This part can be written in many different server side languages such as PHP, python, ruby, java, nodeJS, etc. This also often includes some database lookup.

Many websites need to be dynamic. Indeed some requests require more than just sending back some html content, they imply some other actions. For example, when you buy something online, the program on the server will take your payment details, send them to your bank, check for the bank answer, inform the warehouse that you just bought something and update the product database accordingly. You basically have a whole software running on the server. Also, most websites have their content stored in databases and so any page viewing require some server actions. The server side software car be written from scratch or based on some framework like Django or Symphony, or even, you just install a certain software that is designed for your needs like Worpress. You can safely assume that most of the websites you look at in your day to day life are dynamic (except for this one!).

But maintaining a dynamic website is not simple. Indeed, depending on your server side software, you will need a bunch of different programs installed on the machine and running 24/7. To set up the server, you definitely need some sys-admin knowledge. And if you have a limited access to the server administration, you might not be able to do what you want. For a simple personal website, or a small information website, this might get quite heavy.

That’s where the solution of a static website comes in hand. It is a good solution if the content on the website does not depend on any action of the user: basically, your site is just a collection of pages. Of course, there is the hassle of writing all those pages and updating them. For example, a blog is mostly a collection of blog posts, each blog post being one single page. But every time I write a new post, the home page needs also to be updated to add the new link. The solution is to use a software that automatically generates those pages. The difference with a dynamic website is that it is generated beforehand: not when the user request it, but whenever the content is changed. This generation can happen anywhere (for example, on your own computer) and then the generated files are copied over to the server.

Github pages and Jekyll

The first time I discovered such a system was when I heard of Jekyll and Github pages. It was at the beginning of our European project OpenDreamKit. Since then, the website has been completely rebuilt but the first version was already using Jekyll. I was very easily seduced with the development process and started playing around. In this case, github takes care of most of the trouble for you. First thing to know is that github can offer you some very basic hosting service for your projects: basically you put some html files in some repo and tell github that this is a website. You’re given an access url and also means to redirect your domain name to your github website.

But there is more: Github offers you a Jekyll service. In this case, you website source is hosted on a github repo but it is not directly html files. Your content is stored in some text files that you can directly edit: each page or post is a single file that contains some parameters and the actual content (written in Markdown). The source also contains some configuration files and some html templates. Whenever you push on your repo, Github runs Jekyll, generates the html files and update your website. Note that there is a dynamic part here, taken care by Github. Still, it is a static website in the sense that the content is generated not when the user asks for it but whenever you change the content.

It is a very great service and very easy to use. To better understand the process, you can of course clone your website repo locally and run jekyll yourself. Then, you will see your html files the way they are generated on github. This is what I quickly did because I had to make non trivial changes on the website and wanted to be able to test it locally. But the good part is: not everyone needs to do it. On the OpenDreamKit project, we are about 50 people involved. We all have access to the github repo and can use the online github editing service to push changes to the website. And, the whole collaborative aspects of 50 people working on a shared project is handled through git, with commits, and merge, and versionning, and every thing, which is a big plus.

I was so much seduced by the system that a few months later, when I thought of creating this blog, I decided to use the same system. It had been some time already that most of my computer data was managed through git. The idea of managing my website through command line, text files and git push was very pleasing and felt so very simple. And indeed, it was probably the easiest site deployment ever. For once, I used a ready made theme and everything went smoothly. The only thing I had to worry about was the commenting system. Indeed, comments are the only part in a blog which actually require a dynamic server. I first tried to use some kind of remote database hosting that supposedly would let me store my comments and pull them as static content. After a few month however, it stopped working. I must say, I just did not have to the time to investigate other solutions. I moved to Disqus: it is definitely not the ideal solution but, well, it works.

Discovering Pelican

Some time after that, I volunteered to develop my research team website. It was to be hosted on our department server. For the source, I figured we needed a git repo as I certainly did not want to be the only contributor once the site was live. To host the repo, I could use the gitlab install that was also on the department server which would allow easy access to any member of the team. And of course, I thought that a static generated website was a good solution.

Because I was not going to use the github page system, I did not have to use Jekyll. I looked around to learn about other solutions and came across Pelican. I hesitated quite a bit: indeed I already knew Jekyll, why would I take the trouble to learn another system? At the end, after reading a bit, I still chose Pelican. The fact that it was written in python was a big plus: no gem magic going on. Also, it had a very good multi-language plugin (I use i18n). And I must say, I am quite happy with my choice.

Now that I know both systems quite well, I still have a slightest preference for Pelican. One thing is that I find the architecture clearer: the content is better separated from the configuration and templates. Also, I like very much the fact that I can write my own plugins. If you use Jekyll through a github page system, you cannot install nor write extra plugins. Also, the plugins are in ruby which is somehow exotic for me. In Pelican, the plugins are just some python files and I got the hang of it very quickly.

Whenever I could not find something doing what I wanted, I wrote my own plugin. I did a “drop down menu plugin”, and a “articles on page” plugin, and some others. I wrote my own theme based on Bootstrap. I used the posts, categories and tags to organize the website content in a engaging way that clearly put forward our team activities. The result was nice and my team was very happy.

One problem though was to get some kind of continuons integration: basically, it’s great to have a git repo where other people can contribute but I also want the website to automatically update whenever there is a push. This is the part that is taken care of by Github when you use Jekyll. Here I had no github to do the job for me… I could have looked into gitlab internals and set up a hook or something to some port on the department server that would trigger a script. But I didn’t: it looked like too much work and I didn’t want to open any kind of security breach. So… I used a very basic system: I set up a cron task on my own space which pulled the website and regenerated it every 15 minutes… It is not perfect but it does work! With this plus the repo, I wouldn’t say I got all my team to contribute but after minimal explanations, I did get a few! And, I must say, the website mostly runs without my help.

Quite motivated by this first experience, I then decided to re-write my own academic website using Pelican. I had more experience with Pelican, less constraints and I did not need any continuous integration. Again, I wrote my own theme using my growing Bootstrap experience and copying over some nice things around. And I got my perfect website fully working, easily manageable, using a clever categories / tag system to make it a great showcase of all my academic activities.

Back to Jekyll

At this point, I had built 3 statically generated websites: my blog on Jekyll, and 2 websites on Pelican. And I was about to build a fourth one. Indeed, our original OpenDreamKit website had many flaws and we were thinking on rebuilding it entirely. I took this on me and got back to playing around with Jekyll, trying to adapt some of my Pelican ideas. I was a big fan of my own tag system to organize my academic activities and wanted something similar for OpenDreamKit. I got there but it was not that easy. Indeed, unlike Pelican, Jekyll does not have a good native tag system. And because you cannot install any plugins on a github website, I needed to develop that solely through the templating language (liquid) which is somehow a challenge. But it worked! And I also rediscovered things I like about Jekyll and miss in Pelican like collections, and yml data files. For example, we got our latex proposal file to compile some yml data describing the project (like WorkPackages, tasks and Deliverables) that we could use on the website. The new website was a big hit and had great success among the other participants.

The big WordPress to Pelican challenge

After all this, I still had an itch to scratch. Somewhere on the web, lies my old travel blog. It is 12 years old and had been running on Worpress since 2009. It is not dead: I update it whenever I travel. But I could not remember when I last updated the WordPress version. The theme itself, I had wrote it myself back in 2009. So it was old, many things were broken, many things were out of date. Probably, it had at least a few security breaches. And the sole idea of putting my head into php code tired me. I had nothing against Worpress which had been the perfect companion for many years. But I had moved on… And so, it stroke me: I had to move it to Pelican.

This was not a trivial move. My blog has more than 400 posts so no manual action was possible. Thankfully, WordPress is quite cleverly made and offers an xml export. And, even better, Pelican offers an import from the Worpress xml. It did not work perfectly. Some of my content was chunked for unknown reason. My categories were all messed up (I used multiple categories which is not supported by Pelican). My fix included many little home made scripts to search and replace and inspect the Worpress xml myself. At the end, it was mostly fun to write. It gave me an occasion to go through all my old posts and travels, and re-arrange as I thought best. And there it was, I had my new blog just there on my machine!

The last step was to find a solution to host it. I already had a server so I could just have reused it but my problem came again from the continuous integration. Indeed, for my academic website, I can just regenerate the site whenever I change something. But for my blog, I usually write on the road. Recently, mostly from my phone. I don’t always have a computer with me to turn on whenever I want to publish a post. So I looked around, and here it was: Netlify was proposing this exact service! I found it was very easy to put in place. They had a redirect system which looked like an htaccess file and, using my home-made scripts, I genereated a whole map from my old urls to the new ones. As soon as DNS server had updated my changes, I had my new site up and running! Here it is: Viviane Voyage.

And now I am happy: all my websites are managed through text files and git pushes. I only miss one thing: a GitHub android application that would allow me to commit and push without a fully local cloned copy of the repo. Indeed, I do have git on my phone (nerdy me), but I don’t want a clone of my 400-posts-and-many-pictures travel blog on it! The only solution is to use github website (and explicitly require the desktop version) but it is not very handy. Still, I’m hoping this will be available at some point in the near future.