Website Re-Development

11th August 2013

Until very recently, this website was powered by Drupal. Now although Drupal's great in a whole raft of situations, there are times when either it's overkill for something small, or just doesn't fit into one's workflow. I came to realise that both of these applied to this site, so when it came to re-developing, I decided to abandon Drupal for the site altogether.

In the end, I decided to rebuild the site using Jekyll, along with a few other tools along the way.

This post explains the motivations behind the decision, what I did next and some of the challenges I faced along the way.

The Need for Re-development

There were several aspects that made re-developing my site something of a priority.

First, it wasn't mobile-friendly. I may have been able to get away with that some years ago when I first drafted the site, but now that's just not acceptable. After weighing the pros and cons of a responsive vs a separate mobile site, I decided on the former - and the only way to do that would be to start the front end build again from scratch.

Secondly, the site was running Drupal 6. When I first built the site, Seven was in the offing, but not yet secure or stable enough for production. Staying with Drupal would have meant an upgrade, and moving between versions 6 and 7 isn't trivial.

Lastly, the structure of the site was no longer ideal. My work of late has included open-source development and lots of writing, so a portfolio only told half the story.

Other Factors

Workflow

Though the entire site was content-managed, the vast majority of my time was spent on the blog - the rest rarely changed. Although I had a WYSIWYG editor installed I was far more likely to use raw HTML, and often use the tools I use every day - such as Sublime Text - and then copying between applications, rather than editing in the browser. As such, it made sense from a workflow point-of-view to switch to something that closer resembles my development process.

I've also become quite a fan of Markdown of late.

Bloat

For such a simple site, there sure was a lot of it.

Performance

There were time when the site ran pretty slow. Largely this was down to the fact that I have all sorts of projects running on the same box, and also because there have been times when the site has taken something of a hammering - particularly whe I release a new article. I wanted my site to perform the best it possibly could, without throwing server resources at the problem.

Curiosity

Then there was the final motivation - I wanted to try something a little different. There's no doubt that moving sites from a CMS to static is quite "cool" right now; maybe there was an element of that, but it's also true that the vast majority of the projects I'm involved in use frameworks or CMS's, and I wanted to try stripping back the complexity of those, and try something new. Enter Jekyll, which although I'd looked at I hadn't really used.

What had to Go

In moving from a fully-featured CMS to a static site, there were a number of things that would have to go - or, at least, be re-thought.

Comments

Most of my posts attracted some excellent comments. Clearly comments are something that aren't supported with a static site, at least without using something like Disqus.

However, with comments you always have to weigh up the pros of inviting discussion and gaining useful insight, with the effort involved in fighting spam. I used a number of the tools at my disposal to help the fight on my Drupal site - primarily, moderation and Mollom. I deliberately opted against CAPTCHA - as well as being far from fool-proof, I personally find them a significant hinderance.

Despite my best efforts, the sheer amount of spam - including a week of sustained attacks that had led me to disable comments anyway - made the decision to put aisde the lack of a commenting system in my decision to move to a static site.

Dynamic Image Re-sizing

Drupal's image styles (formerly imagecache) enabled me to upload a single image for something, and have the CMS take care of any necessary resizing. There are solutions for Jekyll, but even then it became clear that this wasn't a priority. I also found that images weren't always resized the way I wanted them, and setting the compression is something that varies according to the image - and can only, I feel, be done by eye. As such, losing this particular piece of functionality wasn't a big deal.

Other Features

Of course Drupal provides many, many other features - either in core, via third-party modules, or by writing your own. But I didn't need anything else. I didn't need to be able to switch themes, to translate content, dynamic views or a hundred and one content types. In fact, the sheer amount of unused functionality just added to the bloat.

Other Advantages

One of the problems with a CMS is that as well as having to keep a backup - preferably in source control! - of all your code, there's also the database to worry about. Indeed, with Drupal in addition to all the content being stored in the database, so too is much of the configuration (fortunately, Drupal 8 is changing this). So that's two things to worry about, and with a database that means scheduled backups. It's also much more complex to use version control with SQl sumps. With a static site, there are no such problems - the whole thing; templates, code, and content is in one place and can be safely stored away in Git.

I've reworked the design slightly, replaced all the CSS and underlying HTML, and tidied up some of the visuals.

Source-code Highlighting

I use a lot of code samples in my posts, so source-code highlighting was a must. Fortunately, Jekyll supports it by default using Pygments.

That said, there are a few steps required to make it work - the actual steps will depend on your system, and what you already have installed.

First, I had to install Pygments. I installed on a Mac, so I already had Python installed, so I simply had to do this:

sudo easy_install pygments

I also needed to ensure it was installed in my _config.yml file:

pygments: true

The next thing I needed to do was create the css file:

pygmentize -S default -f html > css/pygments.css

And the step I forgot for a while, leading to much unecessary head-scratching - including the CSS in my layout!

At first, I struggled to get PHP code to highlight. Turns out that by default, Pygments expects <?php tags, unless you use the startinline option:

{{ "@{{% highlight php startinline "}}%}}

Using Pygments - which formats source-code using CSS - solved one of the problems I had with my existing site, which was that the Javascript-based solution I was using was a little tempremental. It also caused problems on mobile - though to be fair, I do find code quite difficult to read on mobiles regardless. Using CSS to format the code seems much more natural than using a plugin.

Portfolio

To use CMS parlance, Jekyll only supports one "content type", and that's blog posts. In my old site, my portfolio was comprised of a "project" content type, and I felt it would be easier to manage if I had something similar in this version of the site.

https://github.com/flatterline/jekyll-plugins

Blocks

http://stackoverflow.com/questions/8772404/jekyll-not-interpreting-markdown

In _plugins/unident.rb:

module Jekyll
  module UnindentFilter
    def unindent input
      input.lstrip
    end
  end
end

Liquid::Template.register_filter Jekyll::UnindentFilter

https://github.com/agelber/jekyll-rss

Twitter Feed

Another challenge I faced was the Twitter feed, that appears on the front page of the site.

Because it was a static site and this involved dynamic content, it made sense to explore a client-side solutio; i.e., Javascript.

Only a few months previous, this would have been a doddle - however, my website redevelopment came shortly after Twitter finally retired the old REST API - requiring developers to use OAuth, even if all you want to do is fetch a public timeline.

The problem with OAuth, of course, is that your credentials need to be kept well out of view - which makes things difficult if you're building a client-side application.

My solution - as suggested by this excellent article - was to build a simple proxy.

As such, instead of fetching the data from Twitter, my JQuery code simply needed to pass the required URL to my proxy, and then that would be responsible for making the call to Twitter, authenticating using OAuth.

The next challenge was to format the tweets. For this I found Remy Sharp's twitterlib. However, the format method was unsuitable, because it added avatars - unecessary for one person's timeline, I feel - and the format didn't fit the site. Instead, I used the method twitterlib.ify.clean. Here's the code in full:

$(document).ready(function()
{
    $.getJSON('/twitter-proxy.php?url='+encodeURIComponent('statuses/user_timeline.json?screen_name=lukaswhite&count=2&include_rts=false&exclude_replies=true'), function(d){
        var html = '
    '; for (var i=0,len=d.length; i'; // + '">' + twitterlib.time.relative(d[i].created_at) + ''; html += ''; } html += '
'; $('#tweets').html(html); }); });
require 'date'

module Jekyll
  module NiceDate
    def nice_date(input)
      d = input.strftime("%e")
      self.ordinalize(d.to_i) + input.strftime(" %B, %Y")
    end
    def ordinalize(number)
      if (11..13).include?(number % 100)
        "#{number}th"
      else
        case number % 10
          when 1; "#{number}st"
          when 2; "#{number}nd"
          when 3; "#{number}rd"
          else    "#{number}th"
        end
      end
    end
  end
end

Liquid::Template.register_filter(Jekyll::NiceDate)

http://truongtx.me/2013/01/09/display-liquid-code-in-jekyll/