Archive for August, 2006

The Permalink Problem

The conversion from Blosxom to WordPress began (in my head, at least), over a year ago, when I began to consider switching from categories to tags as a way to reduce the “friction” of writing. Blosxom is good at many things, but its filesystem based storage isn’t well suited for tagging. After exploring several possiblilites, I decided I’d move away from Blosxom; eventually I settled on WordPress.

The biggest hurdle I faced was dealing with permalinks. Blosxom supports two styles of permalinks: date-based and category based. I decided to go with category style permalinks (e.g., /weblog/Apple/macbook.html) when I first started using Blosxom because the URIs are “hackable”; you can whack the end (filename) off the URI and you’ve got the URI for the category. This worked fine when the site was category based, but fails with tags. For this reason, I’ve configured WordPress to use date based URIs (e.g., /weblog/2006/01/01/macbook/); I also decided to drop the “.html” bit since its not necessary.

However, Cool URIs Don’t Change. There are plenty of old links to my site out around the Internets, which use category based-permalinks, that I don’t want to break. Even the internal links within existing posts on this site will continue to use the old URIs, at least until I can get around to cleaning them up. I wanted to keep supporting these existing URIs, so I needed to make sure I can support the old permalinks.

WordPress supports category based permalinks, but with some caveats. If I configure the whole site to use category permalinks, then date-based URIs don’t work. If I configure the site to use date-based permalinks, category-based URIs don’t work. After searching for a plugin to help without success, I tried the WordPress forums. When that failed to turn up a solution, I poked around the code looking for a solution.

(A brief aside. If you want to explore the WordPress codebase, I recomment this excellent online cross-reference.)

I ended up creating a simple plugin that uses the “generate_rewrite_rules” action hook to add additional URI rewriting rules to the internal set used by WordPress to resolve each URI. I hope to make it available as a plugin someday when I have time to make it more generic; currently its hardcoded to solve my problem. Here’s the heart of the code, if you want to build your own version:

function add_permalink_style($rewriteobj) {
    $extra_rewrite = $rewriteobj->generate_rewrite_rules('/%category%/%postname%.html', EP_PERMALINK);
    $extra_rewrite = apply_filters('post_rewrite_rules', $extra_rewrite);

    $rewriteobj->rules = array_merge($rewriteobj->rules, $extra_rewrite);

add_action('generate_rewrite_rules', 'add_permalink_style');

To help me test everything, I tossed together a quick and dirty test suite, a simple list of links to test from my browser. The code above allows them all to pass.

Because my old permalinks all included .html at the end, I can use the rewrite rule above to strip it out. I originally was doing that with a mod_rewrite rule in my .htaccess file, but that caused problems for old permalinks to my category archives. Since the mod_rewrite rule was stripping the .html suffix before wordpress could see the URI, category URIs (e.g. /weblog/Apple/OSX/) and category-style post permalinks (e.g. /weblog/Apple/OSX/howto-install-carbon-emacs/) matched the same pattern, and WordPress thought the first example was for a post named “OSX” in the Apple category. I believe this is the same thing thats causing my tag URIs (e.g., /weblog/tag/wordpress/) to fail at the moment; the only workaround I’ve found requires a mod_rewrite RewriteRule, but only works with a browser redirect. I’m still working on this problem, as I really don’t want to use redirects. Also, for reasons I haven’t quite figured out, the above makes category permalinks work (and without a category URI prefix, see below), even though the rule expects a post name (slug) with .html appended- but I’m not going to argue with success.

Another issue I ran into was WordPress always wanting a prefix in front of category archive links. For example, my Apple category’s archive link (by default) was /weblog/category/Apple/. Even though my plugin’s extra rewrite rule seems to make URIs like /weblog/Apple/ work, I wanted the catgeory links on my Archive page to omit the extra prefix, for consistancy. WordPress allows you to change, but not omit, this prefix. I came up with a cheap hack for that problem; since I could already handle the URIs without the prefix, I only needed to change the URIs generated on the archive page via WordPress’ wp_list_cats() function. I was able to do this in my plugin by hooking into the list_cats filter:

function fix_category_links($content) {
    $content = str_replace('/category/', '/', $content);
    return $content;

add_filter('list_cats', 'fix_category_links');

It’s a hack, but it’s a hack that works.

At this time, I believe all the old permalinks from my Blosxom blog (both posts and categories) should work, as well as the new date-based permalinks. A key part of all of this was to import my existing Blosxom content while preserving the filename (slug in WordPress parlance), I’ll cover this and rest of the import process in a subsequent post. If you should find any links that don’t work, especially from external sources, please let me know. Now if I can just fix those tag URIs….


Well, I’ve (mostly) finished my converstion to WordPress. If you’re viewing this site in your browser, the theme you’re seeing is called Tranquility, and I created it about 6 months ago, when I first started trying to convert to WordPress. After a 6 month hiatus, it’s nice to finally show it off. Please leave a comment and let me know what you think.

If you’re reading this in your feed reader of choice, then you’ve successfully been redirected from the old rss feed, or the old Atom 0.3 feed, to my shiny new Atom 1.0 feed. Please come have a look at the website as well.

I’ve done my best to ensure that everything’s still here and still working, including old permalinks. I’ll have another post in the near future discussing the issues I had (and some solutions) with my existing permalinks; for now, please let me know by dropping a comment or an email (see the About page for my email info).

I’ve switched from hierarchical categories to tags; this is the first tagged post, but I hope to tag the older posts as well. You can still browse the old categories in the Archives.

I’ll have more to say about the conversion in the near future. For now, it’s late, and I’m done for the night.

Update: First bug- the tag links below don’t seem to be working. Oops.

This is My Final Post

…to the Blosxom-based blog I’ve run at this location for three years. In fact, my three year anniversary passed silently four days ago.

However, I’m not done blogging yet. As great as Blosxom is, I’m ready for something with less friction. I’ve decided to migrate this site to WordPress.

So what’s in store?

  • Existing posts will remain
  • Existing comments will remain
  • Comments will be reactivated (!)
  • I’ll publish my Blosxom-to-Wordpress conversion method/code
  • Date-based permalinks
  • Existing permalinks will work
  • The categories will remain as archives, but new posts will be use tags
  • I hope to get the old posts tagged as well
  • A brand new layout (finally!)
  • A valid Atom 1.0 feed (I had to hack this in, I’ll publish my code after the conversion)
  • Hopefully, I’ll start posting again!

The timeline’s not set, but I’m hoping to have everything done this weekend. There’s still one major technical issue to overcome, but I’ve asked for help in the WP support forum, and I’m poking around in the code. Stay tuned.