Katie Sak
Katie Sak

Reputation: 119

Changing Wordpress Site URL from Subdomain to Sub Directory

This is a 911; I need to change a Wordpress subdomain URL that I created a GoDaddy WP installation to a subdirectory URL. Can't I just make a folder in my FTP root site folder and transfer the WP files over? No migration plugins work.

I know that I should've installed the WP on GoDaddy on the proper root directory, to begin with, but I didn't think it would be this difficult to fix.

Just so I'm clear I want example.myrooturl.com to be myrooturl.com/example. I need the most straight forward, quickest way to do this if possible

Upvotes: 1

Views: 10183

Answers (5)

surfbuds
surfbuds

Reputation: 555

Modifying serialized data strings containing URLs

This is to add to @Daniel anwser and warn about the danger of doing a simple find and replace on the SQL dump. There are a lot of serialised data stored in the database, and URL are also stored in serialised data strings, especially for menus and image carousels and much of plugin settings.

If you want to do a proper find and replace on an SQL dump, you'll have to update the URL string length attribute in the serialised data.

Personaly I use Git pre-commit and post-receive hooks to automate these tedious and error prone tasks, and make heavy use of perl regular expressions to accomplish this inside the hooks.

However you can do the same via shell scripts and using Perl regexp.

Here is a find-replace routine that has worked well for me on many Wordpress site migration. It uses Perl one-liners. Note that Perl is installed by default on all or most linux distributions and also on MacOsX.

You will have to do find-replace routines also on javascript files and json manifest files generated by plugins or your site could break.

It is recommended to use a test site first to do all your modifications rather than on a production site. Wordpress site can easily break and sometimes it can take a while to find the culprit even for seasoned developers.

Here's an example of a shell script you can run. Define your own variables and path to your shell. It does a smarter find&replace via 2 passes and changes the URL length attribute in serialised data strings.

(obviously "subdomain", "domain" and "tld" must correspond to yours.)

#!/bin/bash -e

# Database info

DBHOST=localhost
DBUSER=mydbusername
DBPASS=mypasswd
DBNAME=mydbname


# Location of SQL dumps

SQL_DUMP_FILE=/path-to-your-sql-dump/dump.sql
MODIFIED_SQL_DUMP_FILE=/path-to-your-modified-sql-dump/dump.sql

# Create original dump file

mysqldump -h $DBHOST -u $DBUSER -p$DBPASS $DBNAME  --skip-extended-insert --skip-dump-date --single-transaction > $SQL_DUMP_FILE



# First pass: find and replace subdomain to subdir, keep original dump and generate new modified file


perl -pe 's/subdomain\.domain\.tld/domain\.tld\/subdirectory/g' < $SQL_DUMP_FILE > $MODIFIED_SQL_DUMP_FILE


# Second pass: Edit serialised data by changing string length parameters when URL detected

perl -i -pe 's{s:(\d+):\\"(http(?:s)*://domain.tld.+?)\\"}{"s:".length($2).":\\\"$2\\\""}ge' $MODIFIED_SQL_DUMP_FILE

Once you're done with the above, you can use your new SQL dump file to build your database on a test site that uses the same domain and sub-directory structure as defined in your find-replace script.

Note: it's not considered safe to write your DB password in a shell script but since you do it anyway in wp-config.php file it's already exposed to anyone with read access to your non-public files.

In a different shell script or the same one you can do something like this:

# Restore or populate new database

mysql --protocol=TCP --port=my-port-number --host=$DBHOST --user=$DBUSER --password=$DBPASS mydatabasename < \
$MODIFIED_SQL_DUMP_FILE

Upvotes: 0

Farhan Ayub
Farhan Ayub

Reputation: 1

Sub-domain or sub-directory is the important part when you installed multi-site WordPress, you will find this option when you are trying to setup your Network on WordPress.If you selected sub-domain then you need to re-install WordPress because it’s a permanent change and the only solution is to re-install and configure the WordPress again. I have attached the pic where you'll find this. Thank you! enter image description here

Upvotes: 0

Jonas Hjalmarsson
Jonas Hjalmarsson

Reputation: 1

I had some trouble after doing all steps I found in different guides. After search and replace my newly changed en.domain.com to domain.com/en my en site didn't show anything. After som troubleshooting I found that I had to change the domain and path as-well in the wp_blogs table, I haven't seen this in any of the guides before I did the domain to subdirectory switch. So I thought I'd give a hint if you are struggling as I did ;)

Upvotes: 0

Amranur Rahman
Amranur Rahman

Reputation: 1133

Rewrite your wp-config.php with this code

define('SUBDOMAIN_INSTALL', false);

instead of define('SUBDOMAIN_INSTALL', true);

then goto:

http://www.website.com/wp-admin/network/setup.php

then:

Add the following to your .htaccess file in /var/www/vhosts/website.com/, replacing other WordPress rules:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

That's it.

Create a New Site with Subdirectory

Upvotes: 1

Daniel
Daniel

Reputation: 2295

I have had to do the reverse of what you're requesting quite frequently. Moving a Wordpress site can be tricky as the site's canonical URL is stored in the database and a lot of the internal links are also stored with the full URL (not a relative one). In my experience this can be done in 5 minutes with a few steps but be prepared for a few minutes of downtime:

  1. Perform a export (backup) of your database and download it to your local machine (backup using the sql format) probably easiest using PHPMyAdmin
  2. Open the sql file in a good text-editor (Notepad++ is good on Windows or Text-Wrangler on Mac)
  3. Perform a "Find and Replace" in the database, find all instances of your current url "example.myrooturl.com" and replace it with the new url "myrooturl.com/example"
  4. Select all text in the file and copy to your clipboard (Ctrl+c or Cmd+c)
  5. Connect to the FTP server using an FTP program (FileZilla is best IMHO)
  6. Create a sub-folder in the site's root directory called "example" (where "example" will be the /example part of the url)
  7. Navigate to the site's root - probably a folder called "example.myrooturl.com" in the root directory
  8. Select all the files in that directory
  9. Drag those files to the newly created "/example" folder
  10. Go back to PHPMyAdmin and paste the copied sql statements from step 4 into a query window - this may take a few seconds to a minute or two for the text to appear in the textarea
  11. Execute the sql query

If these steps were followed and no issues encountered this should be all you need to do! You should be able to navigate to the new URL and view the site.

EDIT

Two things weren't considered: the removal of the sub-domain which, in CPanel, was mapped to the sub-folder we wanted to use; and the fact that the site in the sub-folder would be nested within another Wordpress installation.

The first item is straightforward, remove the sub-domain mapping to the folder and clear browser cache. The second one is more challenging and involves editing the .htaccess in the root of the public_html folder (the one for the main site). This is because when you have a wordpress site nested in another installation, Wordpress is likely not to allow traffic to go to the nested site (site.com/site) and will instead generate a 404 (if a permalink doesn't already exist for the sub-folder name). This is done by editing the htaccess as follows (taken from here)

 # BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]

# Include in the next line all folders to exclude
RewriteCond %{REQUEST_URI}  !(folder1|folder2|folder3) [NC]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress 

It's also worth deleting the old .htaccess from the nested site, logging into the wp-admin, visiting the Settings->Permalinks page and clicking "save" to regenerate the .htaccess in the context of the new installation.

NB @user7357089 suggests performing 301 redirects, this is a good idea to maintain any SEO "juice" that you have as well as prevent broken links. This can be done easily with the .htaccess file - if you have experience here, let me know if you need guidance

Upvotes: 0

Related Questions