This weekend, I moved Random Hacks to Typo, a nifty Rails-based blogging system. Here's what I did:

  • Set up my Mac for Rails development
  • Pointed Typo at MySQL
  • Created a custom theme
  • Wrote an article importer
  • Routed my old URLs to new locations
  • Wrote some custom sidebars
  • Configured Debian's mod_fcgid

Now for the gruesome details.

Setting up a Mac for Rails development

First, you'll need a copy of Rails. MacOS 10.4 ships with a perfectly good copy of Ruby, but it doesn't include Rails, Gems, or any of the extras you'll need.

You can get everything you need in one package from the Rails Wiki; see the section titled "MacOS X Installer."

You'll also want a copy of MySQL, which comes in a nice MacOS X package, and the Rails MySQL adapter.

To browse your MySQL database, you'll almost certainly want to use the gorgeous CocoaMySQL. For editing Ruby code, check out either TextMate or Carbon Emacs with ruby-mode.

Pointing Typo at MySQL

Making Typo talk to a database is hard, and there isn't any feedback: Most errors result in a blank page and a 500 error. You'll probably want to check several things:

  1. Make sure your Rails MySQL adapter is installed correctly.
  2. Download mysql-client from Fink and make sure your database login is correct.
  3. Make sure your config/database.yml file is looking for MySQL in the right place.

The last item deserves some explanation: The default database.yml attempts to communicate with MySQL using Unix sockets. Unfortunately, these sockets are in odd places under MacOS X and Debian.

Your best bet is to fix database.yml to use TCP/IP instead of Unix sockets. Delete any socket lines and set host to 127.0.0.1 instead of localhost.

After you've double-checked all this, you shouldn't have any problems. Take a look at the Typo README file for further instructions.

Once you're done, run script/server and connect to the URL it prints. You should see a setup page.

Creating a custom theme

Themes are easy. Just copy themes/azure to new directory, and start hacking on it. There's a good theming guide on the Typo Wiki. You shouldn't need any programming skills, at least for a basic theme.

Writing an article importer

If you have a pre-existing blog, take a look at the scripts in db/converters. You'll see converters for several popular packages, and for raw RSS and Atom feeds.

If you need to write a custom converter, use one of these scripts as a starting point. The existing converters all run inside a Rails enivornment, and they access the database using ActiveRecord's object API. This is much easier than building SQL records by hand, and it helps get various constraints right.

Routing old URLs to new locations

My old site had short articles in /YYYY/MM/DD, and long ones in /stories/permalink.html. To map these to new locations in Typo, I added a few lines to config/routes.rb:

# Legacy mappings for old Random Hacks site.
map.connect ':year/:month/:day/',
  :controller => 'random_hacks_legacy',
  :action => 'redirect_date',
  :year => /\d{4}/, :month => /\d{1,2}/,
  :day => /\d{1,2}/
map.connect 'stories/:permalink',
  :controller => 'random_hacks_legacy',
  :action => 'redirect_story',
  :permalink => /[-_A-Za-z0-9]+\.html/

This intercepts the requests and forwards them to random_hacks_legacy_controller.rb in the app/controller directory:

# Remap old randomhacks.net URLs.
class RandomHacksLegacyController <
    ApplicationController
  # Redirect a daily page.
  def redirect_date
    year = params[:year]
    month = params[:month]
    day = params[:day]
    url = "/articles/#{year}/#{month}/#{day}/"
    redirect_permanently url
  end

  # Redirect a top-level story.
  def redirect_story
    # We need to call #find directly, because
    # Typo overrides #find_by_permalink with
    # some function that wants a date--which
    # is what we're looking for. Grr.
    id = params[:permalink].sub(/\.html$/, '')
    conditions = ['permalink = ?', id]
    article =
      Article.find(:first,
                   :conditions => conditions,
                   :order => 'created_at ASC')
    redirect_permanently article_url(article)
  end

  # Send a 301 permanent redirect, as
  # described by Lars Pind.
  def redirect_permanently url
    headers["Status"] = "301 Moved Permanently"
    redirect_to url
  end
  private :redirect_permanently
end

There's one special case to be aware of: If you're remapping an RSS feed, you probably want to use an Apache .htaccess file, not a Rails redirect. RSS feeds are downloaded frequently, and Rails can't cache a redirection.

Configuring Debian's mod_fcgid

Debian doesn't include mod_fcgi out of the box, because it isn't free software. Instead, they ship mod_fcgid, which is almost the same. You'll need to make a few changes to your copy of Typo. Start by commenting out these lines in .htaccess:

#AddHandler fastcgi-script .fcgi
#AddHandler cgi-script .cgi
#Options +FollowSymLinks +ExecCGI

Next, make sure you're using dispatch.fcgi:

RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Finally, install mod_fcgid normally. For best performance, you'll want to add the following lines to your Apache configuration. They need to appear at the top level, not inside a Directory or VirtualHost declaration:

IPCConnectTimeout 5
IPCCommTimeout 120
DefaultMaxClassProcessCount 2
DefaultInitEnv RAILS_ENV production

Conclusion

Typo is still fairly hard to set up, espcially on Debian. But it's an excellent piece of software for anybody with a Rails background. It's well-structured, well-tested, and easy to hack.