Migrating Directory Structures of Existing Blogs into a WordPress 3.0 Network

The WordPress Network adventures continue! In migrating existing sites, I found myself facing the challenge of keeping existing non-WP directory structures in place. In one case I had a WordPress site that had non-WP directories littering the root directory, and in another WordPress was installed not in the root but in a sub-directory.

In the first case I did not find an acceptable solution, but in the second case I did. (I should mention that my network uses the sub-domain structure.)

Case 1: Non-WordPress directories in the root

In this case, WP is installed at the root: example.com/. I also have directories at that level — example.com/foo — that contain what might be described as stand-alone, non-WP micro-sites. In the non-network install, WP was being cool and not interfering with them.

Moving it into the network, the site becomes number x. Since blogs.dir/x/files is served as example.com/files, I had hoped I could simply move the directories over as blogs.dir/x/foo and have them served as example.com/foo, but no dice.

What you CAN do is put the directories in the network root. The upside is that they appear as intended for the domain in question. The downside is that they appear for ALL domains in the network. In my case that’s unacceptable.

I’m hoping that in the future a plugin appears to address this issue, but for now the verdict is that it’s not possible. If you or someone you know is working on a plug-in for this, I’d happily put some beer money towards the cause!

Case 2: WordPress installed in a sub-directory

In this case, I have a domain where WP is installed in a sub-directory — example.com/foo/ — and a lot is going on in the other sub-directories. I wanted to migrate the blog without messing up the other directories.

So I created a symbolic link in place of the /foo folder to serve up the network site. Since I’m on MediaTemple, I used the directions in the trusty KB article to create the link. I navigated to the html folder of example.com and did:

ln -s /home/####/domains/wordpress-domain.com/html foo

(### being my server number, wordpress-domain.com being the domain where my WP network is installed, and foo being the directory in question)

When I mapped the domain (using the Domain Mapping plugin), I did so as example.com/foo. And under site properties I added /foo to the path. Doing these things lets me pull up the homepage. Awesome!

But there were two problems: logging-in, and permalinks.


With this mapping, I couldn’t log-in to the site. The problem appears to be that there was a discrepancy between the directory WP thought it was trying to log-in to, /foo/, and the directory where it was actually located, the root.

There’s a plug-in for that! From the description: “By default the wordpress cookie exactly matches the URL of your installation, this plugin removes any subfolders from the cookie so that your whole domain has access to it.”

Be sure to only activate the plug-in for the site in question and not your root site.

Pretty Permalinks

I ran into trouble when I clicked a permalink, or otherwise left the start directory as the rewrite rules from the WP domain’s .htaccess weren’t being applied.

So I grabbed some mod_rewrite code from a test installation, and compared it to that from the root domain. I determined which lines were needed for the file uploads, and which for the permalinks. The problem is that the last line, essential for the permalinks, redirects all requests (the “.” matches any character) through wordpress — including those to the domains we’re trying not to touch!

The way I managed to do it was to put in exceptions for the files and folders I wanted left alone. I would have preferred not to do it this way as it means I have to include a line for each one, but for the scale of the site I was dealing with it was no big deal. If someone knows of a solution that doesn’t involve exclusions, please let me know!

Here’s the finished mod_rewrite:

RewriteEngine On
RewriteBase /foo/
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
# here's the format for excluding files in the root
RewriteCond %{REQUEST_URI} !^.somefile\.html
# and here's the format for excluding directories
RewriteCond %{REQUEST_URI} !^/somedirectory
RewriteRule . /foo/index.php [L]

And that’s it! I imported the site and now I’ve one less WP install to worry about. The site in question for this case, by-the-way, was halfempty.com/wp/.

Any questions or comments, please let me know. I hope this helps you in your own projects.

Posted July 2010

This website is hosted by Media Temple. Thanks, guys!