When I decided to move Coyote Mercury to a new host, I figured I’d take the opportunity to make a slight change in the URL. When I started blogging almost five years ago, I already had Coyote Mercury running as a static site and installed WordPress in a sub-directory, which made the URL coyotemercury.com/blog1. Eventually, the blog became the whole of the site and when I decided to change hosts, I wanted to get rid of that /blog1. It wasn’t a big deal and I could have lived with it, but what I really enjoy is the puzzle of solving problems I create for myself and this looked like a perfect opportunity to do just that.
The main issues would be making sure that all those links from all those other bloggers who’ve been kind enough to link to my site would redirect to the correct pages as well as all of my internal links. I also needed to make sure that the /blog1 rss feed would redirect. What follows is mainly a summary of what I learned and where on the web I found what I needed for anyone attempting a similar move.
Moving My Blog to a New Host & Changing the URL
1. Before doing anything, I used the WordPress export tool to download my WP database to my computer as an XML file. I then FTP’d all my files from my old host to my hard drive, making sure to maintain the exact file structure as it appeared at my old site.
I decided I wanted a clean install of WordPress along with a clean database to start with. There were some things that didn’t work at my old site like pingbacks and my old host didn’t allow the use of .htaccess so I wanted to make sure that everything was installed in such a way as to work well at Bluehost.
2. Bluehost has a one-click WordPress installer and so I used that to start with, installing WordPress in the root directory. Once that was done, I went into cPanel, found the file manager, deleted the new wp-content folder, and uploaded my old wp-content folder (which contains all the plugins, themes and uploads) into the root directory.
3. At this point I had a temporary URL and so I logged into my new WordPress install, went to tools and imported that XML file from step 1. Foolishly, I did not check the box that asks if you want to import and upload attachments. This would come back to haunt me, but I would eventually figure out how to fix it.
4. Once all my posts were imported, I opened up my blog’s dashboard both at my old host and on my new host (where it was running on a temporary URL) and went through each screen to make sure that all my plugins and options were configured the same way. The only difference was on the General Settings page where the WordPress address and the site address on the Bluehost installation were the temporary URL.
This is also wheb I discovered that the media library was empty even though the files were all in the right place. It was a result of the mistake I made in step 3. Keep reading to learn how I fixed it.
5. The next step required me to venture into phpmyadmin and make some changes to my database so that WordPress would function on my URL rather than the temporary URL supplied by BlueHost.
(Disclaimer: If you’re using this post as a guide to moving your own WordPress, please be very very careful with phpmyadmin. Your database is your blog’s memory and it is very easy to perform a lobotomy if you’re not careful. Check your spelling. There is no undo in phpmyadmin. I am not responsible for your site’s database if you try any of this and it doesn’t work for you.)
Using phpmyadmin, I ran the following SQL command, which is based on what I found at My Digital Life:
UPDATE wp_options SET option_value = replace(option_value, 'http://temporary-domain.com', 'http://actual-domain.com') WHERE option_name = 'home' OR option_name = 'siteurl';
If I had decided to maintain the coyotemercury.com/blog1 URL, I would basically be finished. All I would need to do now would be to point the domain name servers from my old host to my new host, but because I was changing the URL, I would need to run a couple more SQL commands in phpmyadmin, both of which came from My Digital Life, where you can find more detailed explanations about the whys and wherefores of all this.
The next SQL command would change the URLs of all my old posts and pages so as to get rid of the /blog1:
UPDATE wp_posts SET guid = replace(guid, 'http://old-domain.com','http://new-domain.com');
The final SQL command rewrote all of my internal links so that they would still point to the correct posts:
UPDATE wp_posts SET post_content = replace(post_content, 'http://old-domain.com', 'http://new-domain.com');
6. Once I was finished running these commands, I logged into my old host’s control panel and pointed the name servers toward Bluehost and waited. For a few minutes nothing worked, then everything was jacked up and then… my site looked right. The images were there. The internal links were correctly rewritten, things looked right. Now, it was time to redirect inbound links.
Redirecting Inbound Links
7. The next thing to do was to make sure that all inbound links still went to the right place. I put a /blog1 subdirectory in the root folder and then used the text editor to write a simple note indicating that the site had moved. I saved it as index.php and put in in the /blog1 folder in case my redirects didn’t work.
8. Permanent (301) Redirects are properly done using .htaccess, which is completely new to me. I read a lot about it at Codeleet, Cats Who Code, and Expression Web, where I learned that Bluehost has a nice redirect feature in cPanel that writes and inserts the .htaccess code for you. I did that and it worked well. I went to a few sites that had links pointing to some of my posts and pages, including the home page, tested them out and it all seemed to work.
Redirecting the RSS Feed
9. Redirecting the RSS feed from /blog1/feed/ was a bit more challenging. I used the redirect feature in cPanel, but it didn’t redirect the feed. This could be a problem since many of my regular readers seem to come via the feed. Without a redirected feed, they might not realize I had moved. I did some research at Cats Who Code, Nanny Goats in Panties, RSS Advisory Board, Advertising Age, Radio Userland, and The RSS Blog where I found the code for an XML level redirect.
I added a sub-directory into my mostly empty /blog1 folder and called it /feed. Then I opened my text editor and pasted the following code from The RSS Blog (with http://domain.com/feed/ changed to reflect the address of my new feed):
<?xml version="1.0" ?>
I saved this file as index.php and uploaded it to /blog1/feed/ and my feed started redirecting.
I’m not sure why, but it seems there needs to be both redirection code in the .htaccess file and an active file from which to redirect.
Making the Media Library Work
10. Like I said back in Step 3, I forgot to tell WordPress to import the attachments from the XML file I had exported in Step 1. The result was that while images displayed in posts, the media library appeared to be empty and when I clicked on images, I got 404 errors instead of attachment pages. After doing some research, I learned that the attachment pages were kept along with posts and pages in the wp_posts table of the database.
To fix things, I went back to phpmyadmin at my old host and exported the wp_posts table to my hard drive as an SQL file. Then, I went to phpmyadmin at Bluehost, dropped (which means deleted) the wp_posts table and then imported the wp_posts SQL file to my new host. Since I had now undone some of what I had done earlier, I had to re-run those last 2 SQL commands in Step 5.
Now, the media library was populated and the attachment pages worked, except where thumbnail images were involved. Wherever thumbnails appeared such as on galleries, they were displaying at full size. I checked to see that the thumbnails were in fact on the server (they were) and then began researching which part of the database contained the info that connected the thumbnails to the attachment pages. Turns out that was in the wp_postmeta table.
11. I went back to phpmyadmin at my old host and exported wp_postmeta as an SQL file to my computer. Then, I went to phpmyadmin at my new host, dropped wp_postmeta and imported the wp_postmeta SQL file from my computer.
Now, I had to run one more SQL command, this one of my own creation, but based on the ones I ran in Step 5:
UPDATE wp_postmeta SET meta_value = replace(meta_value, '/blog1/wp-content', '/wp-content');
And, it worked. For me. Be careful if you try this yourself since your blog may have a different file structure. If it does and you try this, you could damage your database. Of course if that happens you can always go back to Step 1, start over and remember to check that box about importing the media library.
And now I’m done and looking forward to getting back to blogging.