adamwiggall.com

Redirects, Octopress and Heroku

If you change the technology that your website is built on there is a good chance that you will want or need to re-factor during the transition. If you change the URL structure then it’s prudent to make sure that the old URLs get mapped to the new.

This post details how I achieved that moving from a PHP/Apache based ExpressionEngine install, to Octopress running on nginx, hosted at Heroku.

An admission to start with, I’ve been using Apache since I got started on the web, the first hour (or so) of trouble-shooting a mod_rewrite issue on a non apache based server has been written off as one of those mistakes I won’t make again. Hopefully.

301 Redirects

I decided to use the Octopress default url structure of example.com/blog/yyyy/mm/dd/post-title which differed from the structure that I had in place on my old blog of example.com/weblog/entry/post_title. To ensure that Google and my old readers were still able to find the posts they have crawled, indexed and bookmarked I had to put a redirect in place telling users that the url for the resource they were requesting had changed permanently.

Tons of googling left me empty handed until I came across this post by Scott Watermasysk talking about his Octopress customizations. Scott gives a high level view of his changes and invites people to check out his full source code on Github.

Using rack-rewrite to create redirects

In essence we can handle the redirect in the rack up file config.ru through a gem called rack-rewrite. Rack-rewrite is a gem that is…

a rack middleware for defining and applying rewrite rules. In many cases you can get away with rack-rewrite instead of writing Apache mod_rewrite rules

That’s good, because we can’t use Apache, and the implementation is straightforward.

First off, edit you Gemfile to include rack-rewrite as shown in line 19.

Gemfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
source "http://rubygems.org"

group :development do
  gem 'rake'
  gem 'rack'
  gem 'jekyll'
  gem 'rdiscount'
  gem 'pygments.rb'
  gem 'RedCloth'
  gem 'haml', '>= 3.1'
  gem 'compass', '>= 0.11'
  gem 'rubypants'
  gem 'rb-fsevent'
  gem 'stringex'
  gem 'liquid', '2.2.2'
end

gem 'sinatra', '1.2.6'
gem 'rack-rewrite'

Now you can make your edits to the config.ru file to insert your redirects.

config.ru
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
require 'bundler/setup'
require 'sinatra/base'
require 'rack-rewrite'

# The project root directory
$root = ::File.dirname(__FILE__)

use Rack::Rewrite do
  r301 %r{^/weblog/entry/memorial_cup_2009/?$}, '/blog/2009/05/27/memorial-cup-2009/'
end

class SinatraStaticServer < Sinatra::Base

get(/.+/) do
  send_sinatra_file(request.path) {404}
end

not_found do
  send_sinatra_file('404.html') {"Sorry, I cannot find #{request.path}"}
end

def send_sinatra_file(path, &missing_file_block)
  file_path = File.join(File.dirname(__FILE__), 'public',  path)
  file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
  File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
end

end

run SinatraStaticServer

The only changes here to the current stock Octopress are line 3 to require rack-rewrite, and then the magic happens in the use Rack::Rewrite block (lines 8, 9 & 10 above)…

1
2
3
use Rack::Rewrite do
  r301 %r{^/weblog/entry/memorial_cup_2009/?$}, '/blog/2009/05/27/memorial-cup-2009/'
end

Here we are returning a 301 status code r301 if the regular expression we pass %r{^/weblog/entry/memorial_cup_2009/?$} matches the request. Along with the code we instruct the user agent to head to the new url '/blog/2009/05/27/memorial-cup-2009/'.

You can add as many rules as you need, and you can be more adventurous with your pattern matching if need be.

Then you need to jump to the root of your project on the command line and bundle for the gem to be installed and ready to go. Now rake generate your site and test. All being well it won’t be long before your new indexes are updated for all concerned.

Note Subsequent edits made to config.ru may not take if you re-generate your site. I had to restart the server for edits to take.

Comments