No More Website Generators

I never really liked dynamically generated websites. As a guy who lives on the command line, the slow, GUI-required, must-be-constantly-connected approach just doesn't work well for me. What's old is new again, and much of the Internet is going back to static websites. There are a few generators that are worth looking at, but I've had problems with them as well. I'm moving back towards how I used to do web development: no tools at all.

WordPress

When I first started this site, I used WordPress. I was never really happy with it. I couldn't edit my page offline and upload it later. I don't need multi-user support. The layout is a pain to edit. Attaching pictures is tedious.

The worst part was that in order to get any kind of good performance from the site, I needed to cache the pre-generated site from the WordPress database. Therefore, I was ultimately doing everything I could to work around WordPress, meaning that I was using the wrong tool for the job.

If I'm doing everything I can to avoid PHP, mandatory online editing, and dynamic loading, I'm taking WordPress's square peg and forcing it into a round hole. The "features" that define WordPress were getting in my way.

WordPress has its strengths. It allows someone who just wants a basic website to instantly create one with no knowledge of HTML. As someone whose primary HTML editor was Notepad before this (and enjoyed it!), the security vulnerabilities and editing difficulties just aren't worth the trade-off.

Jekyll

I've been using Jekyll to generate this site. It hasn't been too bad. I can easily write an article and upload it to my server. If I have 30 pictures to upload, I can simply drag-and-drop them all in a file browser. Rather than using a "sandbox" plug-in or something of that nature, I can generate the site locally on my hard drive to test how things look.

Then, it started adding features and plug-ins. This isn't terrible; I can choose not to use them. I admit, one or two are nice additions, though. I use postfile which allows me to semi-easily add pictures and other files to the same directory as the article itself rather than keeping thousands of pictures in some "asset" folder.

Then, when I posted two articles in one day, I found that there is no way to tell Jekyll their chronological order. It sorts by filename. Jekyll is open source, so I patched my copy to accept a time as well as a date.

While I may have added a few work-arounds over time to undo or ignore some of Jekyll's functionality, it hasn't been too bad. If this had been the end of the story, though, this article wouldn't exist.

The first time Jekyll broke on me was when I installed it on a new computer. I didn't know there was a new version, and its command line interface had changed. I now needed to run jekyll build rather than the old command. This is purportedly a one-time "future-proofing" change. This is completely understandable.

It also broke all of my plugins and changes. One was a nice break, though: post_url no longer needed to be patched in; it is now part of Jekyll's core. Nothing else worked, though.

I spent some time getting them to work again. While I can't hold this completely against Jekyll itself, I don't know the language Jekyll is written in: Ruby. Fixing these plug-ins required me to hack in a language I didn't know with no plug-in API documentation. It seems that to write a plug-in, you already need to know how Jekyll does things internally. Everything I found on the Web was for the old version.

It's fine. The hurdle's jumped. It comes with a software tool's rise in popularity and becoming bigger. Jekyll was trying to make itself more extensible and easier to use. Having every command begin with jekyll rather than using a loose collection of other keywords is a good idea. After all, someone may already have a non-Jekyll related serve command on their system.

Then, there is something that isn't Jekyll's fault, but it comes with its design decisions. As mentioned, Jekyll is written in Ruby. It requires many packages and libraries to run, including the Ruby interpreter itself.

Ruby updated.

This caused Jekyll to completely break. While not being Jekyll's fault, it did add another layer of unreliability to using Jekyll. I couldn't add to or modify my site because of this until Jekyll was fixed. Eventually, everything was fine again, but it took a while. I debated on leaving Jekyll.

When I switched from WordPress, I had to almost rewrite every article I had. All of the text formatting had to be redone from WordPress's format to either Markdown or Textile. Naturally, once I completed this, a new feature was added the Jekyll to import a site from WordPress.

After comparing my two options, I chose Textile. I liked the syntax, and it gave me the versatility and power over my formatting that comes with using raw HTML. As a basic example, there is no way to center anything in Markdown.

Now is the future, and naturally I chose incorrectly. While I believe Textile to be superior from a formatting standpoint, there is now a huge amount of support for Markdown. Textile is practically unheard of at this point. If I am going to switch from Jekyll, I have to reformat everything again.

I looked at Discount, a C implementation of Markdown. It's extremely fast and includes one or two additions to Markdown that I believe make the language much more practical, including the ability to center. I started to write a Textile parser in C, but I don't think I'm going to bother. It's a dying language. I feel like I'd be the only person on the Web still trying to use it.

Jekyll has one other problem: it's slow. Each time Jekyll is run, it regenerates the entire site, and I'm pretty sure it only handles one article at a time. I, like most people, have a multi-core system. Jekyll should be capable of multi-threading if it runs this slowly.

After all this, I realized that I'm going through the same motions as with WordPress, albeit to a lesser extent. I finally admitted this to myself when I hit my latest Jekyll/Ruby problem:

/usr/local/lib64/ruby/gems/2.0.0/gems/execjs-2.0.2/lib/execjs/runtimes.rb:51:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
        from /usr/local/lib64/ruby/gems/2.0.0/gems/execjs-2.0.2/lib/execjs.rb:5:in `<module:ExecJS>'
        from /usr/local/lib64/ruby/gems/2.0.0/gems/execjs-2.0.2/lib/execjs.rb:4:in `<top (required)>'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/local/lib64/ruby/gems/2.0.0/gems/coffee-script-2.2.0/lib/coffee_script.rb:1:in `<top (required)>'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/local/lib64/ruby/gems/2.0.0/gems/coffee-script-2.2.0/lib/coffee-script.rb:1:in `<top (required)>'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/local/lib64/ruby/gems/2.0.0/gems/jekyll-coffeescript-1.0.0/lib/jekyll-coffeescript.rb:2:in `<top (required)>'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/local/lib64/ruby/gems/2.0.0/gems/jekyll-2.0.3/lib/jekyll.rb:73:in `<top (required)>'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/lib64/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
        from /usr/local/lib64/ruby/gems/2.0.0/gems/jekyll-2.0.3/bin/jekyll:6:in `<top (required)>'
        from /usr/local/bin/jekyll:23:in `load'
        from /usr/local/bin/jekyll:23:in `<main>'

It's time for a change.

The New Tool: A Shell Script

Common to Jekyll: Using Markdown

I recently read an article, It's OK Not to Use Tools by Jonas Downey.

Today, a basic HTML/CSS site seems almost passé. But why? Is it because our new tools are so significantly better, or because we’ve gone overboard complicating simple things?

While there are many markup languages now, they all are just simplifications of HTML. There are a few reasons to use a higher-level language than raw HTML, though:

I've bundled the source code for the current release (2.1.6) of Discount with my web content. This means that no amount of upgrading will break my site anymore. If Discount 3 ever appears, it won't break my site until I choose to update my site to use it, if ever. I no longer rely on rdiscount. With Discount, I also get SmartyPants punctuation, which I prefer.

The longest part is to convert all of my current archive to a unified format.

Other Required Features

There are a few other things I need to make life easier:

This can all be done with a simple shell script. I wrote one that ended up being remarkably similar to sta.sh. The only real difference is that I don't really use awk for anything, so I don't really know it. Mine is completely sed based. I also rely on bash 4 features rather than being sh based. I also use rsync rather than removing and recopying the entire destination directory on each build.

My final script uses symlinks rather than copying the files, so I won't have multiple copies of pictures and large files on my hard drive.

Comparison

 Jekyll  Shell Script 
 (Copying) 
 Shell Script 
 (Symlinks) 
First Run40 seconds20 seconds1-2 seconds
Rebuilding with 1 File Changed10 seconds< 1 second< 1 second

What Does This Mean?

While the script is highly customized to my workflow, being that I wrote it, it is extremely fast and extensible. It is still single-threaded, but it runs so fast that I don't care.

I had originally created the script as a GNU Makefile, but make 3.82 broke a lot of what I use at work. make 4 is coming soon, and I'm expecting a nightmare. I'd rather keep it simple. The reason for creating this script is to remove my reliance on ever-changing tools, and the parallelization advantage I may have gotten is pointless. I'm now limited to the speed my hard drive can manage, and sub-second run times are more than adequate for a hobby site. I wasn't expecting such performance.

This means that the drafts I've been writing and the bookmarks I've been keeping for the past few months may finally be used now. I can write again!