Use .htaccess to redirect from Drupal to WordPress

As I mentioned, I just converted from Drupal to WordPress, and one of the most difficult parts of the conversion was figuring out how to redirect Drupal's old urls to the new equivalents in WordPress.  I'd taken care to carry over ID values intact, so the mapping was easy, and Apache should have been quite capable of doing the url translation for me, but it took a fair bit of trial and error to get it to work right.

Here's the file that finally worked:


#
# Apache/PHP/Drupal settings:
#

# Various rewrite rules.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on

# Rewrite drupal urls to worpress
RewriteCond %{QUERY_STRING} ^q=node/(.+)$
RewriteRule ^(.*)$ http://blog.componentoriented.com/?p=%1 [R=301,L]

# Forward RSS feed
RewriteCond %{QUERY_STRING} ^q=rss.xml$
RewriteRule ^(.*)$ http://blog.componentoriented.com/?feed=rss2 [R=301,L]
RewriteCond %{QUERY_STRING} ^q=atom/feed$
RewriteRule ^(.*)$ http://blog.componentoriented.com/?feed=rss2 [R=301,L]

</IfModule>

Notice the use of RewriteCond before RewriteRule.  When I originally tried this, I used only the RewriteRule statement and tried to match the query string in the first part of the RewriteRule statement.  Needless to say, it didn't work.

The problem turned out to be that RewriteRule just wouldn't match query strings (which is where the node ID was), and when I figured out how to use RewriteCond, that turned out to be exactly what I needed.  The %1 instead of $1uses the value that was matched in the previous RewriteCond statement rather than the matched value in RewriteRule.

Finally, you can see that I also forwarded the old Drupal RSS feeds.  If you're converting from Drupal, this should work for you, and if you're converting from anything else, hopefully this example will help a bit.

22 Replies to “Use .htaccess to redirect from Drupal to WordPress”

  1. I can't think of the specific plugin name but you can use a WP plugin to do all this for you and convert the database as well….

    1. If you find it, let me know. Otherwise, this seems to work reasonably well. About the only place where the .htaccess solution appears not to do the trick is if there's an automated system accessing the URL – some seem to follow the 301 redirect, and others don't. If the plugin solution works better, that might be worth a look.

  2. Yeah i would also be interested if you manage to find that plugin, ive got two drupal sites that ive wanted to transfer for ages but been scared to do so… Im going to give this htaccess a try on a test server and see if i cant iron out the problems you mentioned… I hate htaccess… its voodoo 🙂

    1. I still have not seen that plugin, but I haven't really been looking for it because I've had no issues whatsoever with the htaccess script above. Prior to discovering the bit about RewriteCond vs. RewriteRule, I'd have agreed that htaccess was voodoo, but once I discovered that little gem, it almost makes sense!

      Good luck with your conversion!

  3. Yeah i would also be interested if you manage to find that plugin, ive got two drupal sites that ive wanted to transfer for ages but been scared to do so… Im going to give this htaccess a try on a test server and see if i cant iron out the problems you mentioned… I hate htaccess… its voodoo 🙂

  4. I still have not seen that plugin, but I haven't really been looking for it because I've had no issues whatsoever with the htaccess script above. Prior to discovering the bit about RewriteCond vs. RewriteRule, I'd have agreed that htaccess was voodoo, but once I discovered that little gem, it almost makes sense!

    Good luck with your conversion!

  5. Pingback: HowtoMatrix
  6. Thanks, I've been trying to get Drupal RSS feeds to Feedburner and all the htaccess rewrite's I found failed to work… your's was the first to work. Obviously I used a 302 rewrite, not a 301.

  7. Great post. I’ve had Permalinks installed on my old Drupal site and so I think I can’t use these node ID to post ID. My url’s didn’t come along cleanly when importing the Drupal database to the WP database. Special characters remain in the slug, so you get this/kind/of/url or this-;-kind. Pretty odd.

    Do you know of a way to clean up all these url’s? The location of the bad url’s in the WP database is the post_name field in wp_posts. I could use a SQL query to replace all special characters with a dash, but that doesn’t ensure the same link structure as in Drupal.

    What I could also do is a query to fill the post_name field with the url’s from the Drupal database. The ID’s of the article would be the reference as to what url would come where.

    Do you have a query that would point me into the right direction? Would be eternally grateful!
    (hope you do have some knowledge on SQL queries)

    1. I don’t have a SQL query to do this, though I suppose it’s possible. If you don’t have gobs of links to fix, you might consider installing a broken link checker addin for WordPress (probably not a bad idea in any event) — this would help you find all the links you need to adjust. I’d bet it wouldn’t be too bad unless you’ve got many hundreds or more links to fix.

    2. check http://modeling-languages.com/migrating-drupal-6-to-wordpress-3/ to see how to crop the url in drupal to get only the last part and use this as permalink in wordpress. Then the redirection plugin in wordpress could be configured to redirect all former links to the new ones. 

  8. Great post. I’ve had Permalinks installed on my old Drupal site and so I think I can’t use these node ID to post ID. My url’s didn’t come along cleanly when importing the Drupal database to the WP database. Special characters remain in the slug, so you get this/kind/of/url or this-;-kind. Pretty odd.

    Do you know of a way to clean up all these url’s? The location of the bad url’s in the WP database is the post_name field in wp_posts. I could use a SQL query to replace all special characters with a dash, but that doesn’t ensure the same link structure as in Drupal.

    What I could also do is a query to fill the post_name field with the url’s from the Drupal database. The ID’s of the article would be the reference as to what url would come where.

    Do you have a query that would point me into the right direction? Would be eternally grateful!
    (hope you do have some knowledge on SQL queries)

    1. I don’t have a SQL query to do this, though I suppose it’s possible. If you don’t have gobs of links to fix, you might consider installing a broken link checker addin for WordPress (probably not a bad idea in any event) — this would help you find all the links you need to adjust. I’d bet it wouldn’t be too bad unless you’ve got many hundreds or more links to fix.

    2. check http://modeling-languages.com/migrating-drupal-6-to-wordpress-3/ to see how to crop the url in drupal to get only the last part and use this as permalink in wordpress. Then the redirection plugin in wordpress could be configured to redirect all former links to the new ones. 

  9. I’ve been searching all day and that is the first blog article that is of use.
    Unfortunately a simple re-direct in the .htaccess won’t do the trick
    here since the parameter ?q=node/## needs to be converted to ?p=## on
    the WordPress side.

    1. I’m glad this was of some help.  The conversion I did was quite some time ago, and I’m not sure how well it’s stood the test of time.  I’m contemplating one more conversion, however, so I may end up revisiting this again — thanks for the pointer.

  10. I’ve been searching all day and that is the first blog article that is of use.
    Unfortunately a simple re-direct in the .htaccess won’t do the trick
    here since the parameter ?q=node/## needs to be converted to ?p=## on
    the WordPress side.

    1. I’m glad this was of some help.  The conversion I did was quite some time ago, and I’m not sure how well it’s stood the test of time.  I’m contemplating one more conversion, however, so I may end up revisiting this again — thanks for the pointer.

Comments are closed.