Running WordPress Feeds Through FeedBurner

I like stats. I use Google Analytics to track standard web stats, but it relies on javascript and can’t track subscriptions to my RSS feeds. Enter FeedBurner.

FeedBurner lets you publicize, optimize, analyze, and monetize your RSS feeds – basically putting your standard RSS feed on steroids. You tell FB where it can find your blog feed (mine’s at and it produces a souped up version that can be downloaded from a FeedBurner URL (e.g. Once you have this new feed URL, you just need to get your subscribers to download it from the new location. Easy enough for new subscribers, but what about existing ones? I want my stats to include all readers, not just existing ones.

A little WordPress background is in order. WP processes all pages on your blog, including your feeds, through a PHP file called index.php. It uses a couple of mod_rewrite rules to make this happen.

# Apache mod_rewrite rules that rewrite URLs from:
# OLD:
# NEW:
# OLD:
# NEW:
# Etc… for rdf, rss2, atom
RewriteRule ^(feed|rdf|rss|rss2|atom)/?$ /index.php?&feed=$1 [QSA,L]
RewriteRule ^feed/(feed|rdf|rss|rss2|atom)/?$ /index.php?&feed=$1 [QSA,L]

Its important to get this to avoid a gotcha later. Your subscribers download your feed from a URL that looks like this but WP processes that request like this Your feed subscribers will use the first URL, even though WP uses the second internally. Nobody subscribes to the index.php?feed=atom version of your feed but we’ll use that when we tell FB where it can find your feed.

Now that that’s out of the way we can get started.

Step 1: Setup Your FeedBurner Feed

The first thing you need to do is tell FeedBurner where to find your feed. There is an important gotcha here – use a WP feed url with index.php in it, don’t use the rewritten WP feed URL. In my case, I told FB that my feed was located at FB now makes my souped up feed available at The reason you need to tell FB to use the index.php url and not your rewritten URL is that we’re going to tell Apache to redirect subscribers to our old feed URL to the new FeedBurner URL. See the problem? If FB is grabbing the URL from the rewritten URL, but we’re redirecting the rewritten URL to FB, it gets caught in a loop and never actually gets any feed content. Make sure you’re using the index.php?feed=something URL when setup your account with FB.

Step 2: Redirecting Old Subscribers to the New URL

We’ll use some custom mod_rewrite rules to redirect feed readers from the old WordPress feed URLs to the new FeedBurner URLs. Modify the feed-related rules in your .htaccess file to redirect to FeedBurner.

# Replaced /index.php?feed=$1 with my FeedBurner URL
# The R in brackets tells apache that this is an external redirect
# The L means this is the last rule for processed for the URL
RewriteRule ^(feed|rdf|rss|rss2|atom)/?$ [R,L]
RewriteRule ^feed/(feed|rdf|rss|rss2|atom)/?$ [R,L]

I also updated some other rules that I originally setup when I moved to WordPress from TypePad:

RewriteRule ^adam/atom.xml$ [R,L]
RewriteRule ^adam/index.rdf$ [R,L]

After this, test the rules. Go to your old, rewritten feed url (e.g. in a browser and you should be redirected to your FeedBurner URL. FB will detect that you’re using a browser to display your feed and it will add some markup to it to make it easy to read (not just XML).

Step 3: Making Redirects Permanent

This step is optional but some will find it useful. At this point your redirects are temporary – feeds readers will still come to you first and they’ll be redirected to the FeedBurner URL each time. If you use a permanent redirect, many feed readers will update their subscription data so they go directly to the FB URL and don’t have to come to your first. To do this, you need to change your rule modifiers from [R,L] to [R=permanent,L].

RewriteRule ^(feed|rdf|rss|rss2|atom)/?$ [R=permanent,L]
RewriteRule ^feed/(feed|rdf|rss|rss2|atom)/?$ [R=permanent,L]

Tags: , , ,


Painless Switch from TypePad to WordPress

Earlier this week I switched my blogging platform from TypePad to WordPress. TypePad is a hosted service and its been REALLY slow lately, its feature-set has stagnated, and it reports barely any statistics. Switching to WordPress would give me tons of power and flexibility.

But switching isn’t easy. It was critical to me not to have any down time and and not to break incoming links. Links from other people or from search engines needed to “just work”.

If I had been using the default TypePad URL I would have been up-a-creek, but I used their domain mapping function and my blog has always served pages at Because I control that domain and its DNS I could manage the switch more easily.

The first thing I did was setup the new WordPress site on one of my servers. The new site was “located” at but was still working at TypePad. Having two live sites with similar URLs made it easy to test links. Just grab a link from the old blog, remove the “www”, test it, etc. When I was finally ready to switchover, I would just change the “www” CNAME DNS record to point at instead of at Easy.

TypePad shares an export format with its cousin MovableType. My old TypePad urls took the format adam/{year}/{month}/{name}.html. I setup WordPress to do something similar. In WordPress Admin, Options, Permalinks, set Structure to this value:


OK – lets import the posts from my old blog. The WordPress/Movable Type importer worked great, but my new post URLs didn’t map very well to the old ones.

OLD: /adam/2005/10/refactoring_wit.html
NEW: /2005/10/refactoring-with-pickaxe/

Arghh. The TypePad exporter didn’t include the post “name” (called a “slug” in WordPress lingo) so WordPress created its own. That’s not gonna work. I could workaround the missing “adam” in the URL or the extra “.html” at the end (more on that later), but I needed my post names to come through. TypePad custom templates to the rescue.

All TypePad pages are created using templates. These templates have variables and you can use these variables to do a “mail-merge” to create new documents. If I could create a template that could mail-merge my posts into the standard TypePad export format, but add the post name, then tweak the WordPress importer to recognize and save the post name, I’d be good to go.

Here’s the custom export template I created, and here’s the new importer. I had to make three changes to the old importer: I added a section that would import the correct post name; I removed the old post name section; and I worked around some extra line breaks in the PING parsing section. If anyone wants to see a diff, just ask. I exported my data (I actually did it a bunch of times, made tweaks, reset the database, and started over), imported it into WordPress, and now my new URLs are much closer to what I need.

The custom-export custom-import tweaks go me this far…

OLD: /adam/2005/10/refactoring_wit.html
NEW: /2005/10/refactoring-with-pickaxe/

…but now I needed to make sure that WordPress would respond correctly to the old URLs. That’s where Apache’s mod_rewrite module comes in. mod_rewrite lets you take in incoming URL, slice-and-dice it, and rewrite it in another format.

The first custom mod_rewrite rule I added maintains my permalinks. Any URL coming in that starts with “adam” followed by a 4-digit-year and a 2-digit-month, and ending in “.html” would be handled exactly like the sample WordPress URL above… we would pass WordPress the year, month and name variables and everything would work as expected.

# Rewrite old permalinks to new location
# FROM: /adam/2005/12/article_name.html
# TO: index.php?year=2005&monthnum=12&name=article_name
# Same as 2005/12/article_name/ in new system
RewriteRule ^adam/([0-9]{4})/([0-9]{1,2})/(.*).html$ /index.php?year=$1&monthnum=$2&name=$3 [QSA,L]

The next custom rule allowed me to maintain the old calendar archive links. These links are similar to the permalinks above but don’t have a name.

# Redirect montly archives to new location
# FROM: adam/2005/12/index.html
# TO: index.php?year=2005&monthnum=12
RewriteRule ^adam/([0-9]{4})/([0-9]{1,2})/index.html$ /index.php?year=$1&monthnum=$2 [QSA,L]

The next rule makes sure the old category links are maintained too.

# Rewrite old category links to new location
# FROM: adam/blogging/index.html
# TO: index.php?category_name=blogging
RewriteRule ^adam/(.*)/index.html$ /index.php?category_name=$1 [QSA,L]

One gotcha when importing categories – TypePad uses underscores (_) to separate multiple word category names, and WordPress uses dashes (-). Version 2 of my importer should take this into account, but for now, I just changed my two multi-word categories using the WordPress admin functions.

The last custom rule was important to make sure that old feed/rss subscriptions still worked.

# Rewrite old RSS links to new location
# FROM: adam/atom.xml
# TO: index.php?&feed=atom
# FROM: adam/index.rdf
# TO: index.php?&feed=rss
RewriteRule ^adam/atom.xml$ /index.php?&feed=atom [QSA,L]
RewriteRule ^adam/index.rdf$ /index.php?&feed=rss [QSA,L]

These rules should all come before the default WordPress rules.

Now that all the old links are working (remember the remove-the-www and test trick I mentioned above?) I was set to make the old site live. I changed the DNS so that points to the new site at and then started watching my error logs. Those would be the first indicator of broken links. I added a favicon and a robots.txt file, but that was it – everything else (except for some Google-cache issues) worked.

The only minor irritation was that feed-readers “lost track” of which posts my subscribers has already read. That’s because the last-modified date and e-tag data from the old server was lost in the transfer. Not a big deal, and its a small one-time cost. After a few days on WordPress I have no regrets from making the switch.

Tags: , ,

No Scanning with Google Reader

My test of Google Reader only lasted a day. Serious RSS readers will find fundamental usability problems with the GR approach.

I currently use FeedDemon to monitor 61 RSS feeds. I don’t have the time or desire to read 61 feeds worth of posts every day, so I scan headlines, read the posts I want, and mark the rest as "read" so I don’t have to see them again. FeedDemon makes this "river of news" approach to RSS reading very easy with its surfer style. I don’t need a feed reader, I need a feed scanner. A client that makes me "read" all posts is far too restrictive. And that’s the problem with Google Reader.

Google Reader makes me read every post before it gets marked as "read" and sent to the bit-dumpster. An email client that made you read all your spam before you could delete it would drive you bonkers, but that’s exactly what GR is doing here.

I had hoped that GR would fulfill the promise of fast-feed-access-from-any-networked-computer in the same way Gmail has for email.  But I’ve also known FeedDemon’s author Nick Bradbury for years. You won’t meet a
nicer guy or a better software developer/designer. It felt sorta treasonous to consider a switch away from FeedDemon. Lucky for me I won’t have to deal with any inner-conflict because Google Reader is not an option at this point.

Google Reader might work well for users who are just getting started with RSS but it is far too restrictive for anyone scanning more than a handful of feeds everyday.

Posted in RSS

When Will Gmail do RSS?

I’ve been using Gmail exclusively for personal email over the last few weeks. The transition was easy – just forward legacy accounts to Gmail and setup Gmail to send/reply using these addresses too. Fast, super-threaded email available from any connected computer. No more synching gigantic Outlook PST files between desktop and laptop.

I’m struck by the relevancy of the Adsense ads I see next to my email conversations – soccer ads, triathlon ads, programming ads…

It begs a question – why isn’t Google making money off of RSS feed content? They already use context-sensitive ads to monetize search, web and email content – so why not RSS feed reading? I’m not talking about embedding Adsense in feeds (written on that before) but about a Google-powered feed reader. Like Gmail it’ll be as fast and functional as a desktop app but accessible from anywhere.

Google’s leaving money on the table by not making it easy for me to read my feeds from Gmail, and Google doesn’t leave money on the table. That’s why this is a WHEN and not a WHY question.