Extracting WordPress subsites from multisite can be an arduous challenge if you are unfamiliar with the multisite database and folder structure. This guide walks you through step by step to extract the subsite from multisite using WP-CLI and bash.
If it any point you struggle with this and want the subsite extracted for you then feel free to get in touch on Codeable.
Converting WordPress Multisite Subsite to Single Site with WP-CLI and bash
Create Temporary Folders
Here wp-bullet.com is the multisite domain
The subsite I want to extract is the subdomain guides.wp-bullet.com
mkdir /tmp/wp-bullet.com/
mkdir /tmp/wp-bullet.com/guides.wp-bullet.comNow the basic folders exist for our multisite and subsite.
Extracting Database for Subsite
Enter your multisite root, usually in a similar path to below, remember to change your multisite path (wp-bullet.com)
cd /var/www/wp-bullet.comBefore getting a list of all subsites here is the basic structure of the folders
| Info | Subsite 1 Values | Subsites > 1 Values |
|---|---|---|
| blog_id | 1 | 2 |
| Database prefix | wpb_ | wpb_2_ |
| Plugins folder | wp-content/plugins | wp-content/plugins |
| Themes folder | wp-content/themes | wp-content/themes |
| Uploads folder | wp-content/uploads | wp-content/uploads/sites/2/ |
Get a list of all subsites with WP-CLI
wp site listYou will get this formatted output below which is critical to extracting the WordPress subsite correctly.
The blog_id is 2 which the database prefix is made up of for the url value guides.wp-bullet.com subsite
+---------+------------------------------------------+---------------------+---------------------+
| blog_id | url | last_updated | registered |
+---------+------------------------------------------+---------------------+---------------------+
| 1 | http://wp-bullet.com/ | 2017-02-14 16:09:14 | 2017-01-31 11:35:34 |
| 2 | http://guides.wp-bullet.com/ | 2017-02-21 21:30:15 | 2017-01-31 11:37:04 |
| 3 | http://security.wp-bullet.com/ | 2017-02-21 21:30:48 | 2017-01-31 11:37:33 |
+---------+------------------------------------------+---------------------+---------------------+WP-CLI allows you to export database tables specific to each subsite by simulating that the request came from the subsite’s URL.
wp db export --tables=$(wp db tables --url=guides.wp-bullet.com --format=csv --skip-plugins --skip-themes --allow-root) /tmp/subsite.sql --allow-rootGet the WordPress database prefix from wp-config.php with grep
grep "table_prefix" wp-config.phpHere wpb_ is the database prefix
$table_prefix = 'wpb_';The subsite database prefix is made up of the multisite prefix wpb_ and the blog_id (subsite id) 2 for the wp-bullet.com multisite’s subsite guides.wp-bullet.com
If your blog_id is 1 then you should skip this step!
This uses sed to replace the database table names and redirect to a new sql dump we can use to import into the single site installation.
sed "s#wpb_2_:#wbp_#g" /tmp/subsite.sql > /tmp/wp-bullet.com/guides.wp-bullet.com/database.sqlIf you are copying the database – regardless of your blog_id – to a remote location you can gzip it so it’s much smaller
gzip /tmp/wp-bullet.com/guides.wp-bullet.com/database.sql -c > /tmp/wp-bullet.com/guides.wp-bullet.com/database.sql.gzExtracting WordPress Subsite Contents
We need to compress these folders and extract them to the new singe site installation later
- WordPress plugins
- WordPress themes
- WordPress wp-content uploads which contains images, videos etc for that subsite
Compressing the plugins is done from the multisite root folder wp-bullet.com
tar -czf /tmp/wp-bullet.com/guides.wp-bullet.com/plugins.tar.gz -C /var/www/wp-bullet.com/wp-content/plugins/ .Similarly, compressing the themes folder is done from the multisite root folder wp-bullet.com
tar -czf /tmp/wp-bullet.com/guides.wp-bullet.com/themes.tar.gz -C /var/www/wp-bullet.com/wp-content/themes/ .If your blog_id is 1 then you should skip this command
The wp-content uploads folder is specific for the subsite using 2 as your blog_id (subsite id) for the 2 subfolder in the uploads/sites folder
tar -czf /tmp/wp-bullet.com/guides.wp-bullet.com/uploads.tar.gz -C /var/www/wp-bullet.com/wp-content/uploads/sites/2/ .If your blog_id is 1 then you should use this command since the is special and has its uploads folder in the root of wp-content rather than in the sites subfolder of the uploads folder.blog_id 1
Just excluding the sites subfolder with the other subsites’ uploads folders provides a tar for just blog_id 1 subsite
tar -czf /tmp/wp-bullet.com/wp-bullet.com/uploads.tar.gz -C /var/www/wp-bullet.com/wp-content/uploads/ . --exclude=sitesNow you have 3 tar files containing the essential components for your WordPress multisite subsite.
/tmp/wp-bullet.com/guides.wp-bullet.com/plugins.tar.gz/tmp/wp-bullet.com/guides.wp-bullet.com/themes.tar.gz/tmp/wp-bullet.com/guides.wp-bullet.com/uploads.tar.gz
The database has both an sql and gzipped versions
/tmp/wp-bullet.com/guides.wp-bullet.com/database.sql/tmp/wp-bullet.com/guides.wp-bullet.com/database.sql.gz
These tars will be extracted to the single site in the next section.
Restore Converted Subsite to Single Site
We need to perform the following tasks to make the converted multisite subsite to single site
- Import the WordPress database from subsite to single site
- Search and replace in the database
- Extract wp-content tars from subsite to single site
- Fix permissions if necessary
Import WordPress Database from Subsite to Single Site
Enter your fresh single site installation with your WordPress files, here it is guides.wp-bullet.com but if you made a new domain name just replace that value.
cd /var/www/guides.wp-bullet.comImport database for the subsite and import it into the WordPress single site installation
wp db import /tmp/wp-bullet.com/guides.wp-bullet.com/database.sqlIf you want to use a different domain or subdomain name then do a search and replace with WP-CLI.
If you are using a subdomain that you want to keep the same then you can skip these next two search-replace steps.
It uses guides.wp-bullet.com as the original string to find and wp-bullet-guides.com as its replacement
wp search-replace "//guides.wp-bullet.com" "//wp-bullet-guides.com" --dry-run --allow-rootThis will perform the actual replacement
wp search-replace "//guides.wp-bullet.com" "//wp-bullet-guides.com" --allow-rootRegardless of your subdomain choice you should do a search-replace command for the old and new main domain path.
You should replace your multisite path wp-bullet.com with your new single site path wp-bullet-guides.com.
The --dry-run flag only shows you which replacements will be made.
wp search-replace /var/www/wp-bullet.com /var/www/wp-bullet-guides.com --dry-run --allow-rootPlease replace your multisite path wp-bullet.com with your new single site path wp-bullet-guides.com.
You can do the actual search and replace by omitting the --dry-run flag
wp search-replace /var/www/wp-bullet.com /var/www/wp-bullet-guides.com --allow-rootIf you happen to have additional problems you may want to read the advanced database search and replacement guide for WordPress.
Extract wp-content
Extract the themes.tar.gz to your new single site installation
tar -xf /tmp/wp-bullet.com/guides.wp-bullet.com/themes.tar.gz -C /var/www/guides.wp-bullet.com/wp-content/themes/Next, extract the plugins.tar.gz to your new single site installation
tar -xf /tmp/wp-bullet.com/guides.wp-bullet.com/plugins.tar.gz -C /var/www/guides.wp-bullet.com/wp-content/plugins/Finally, extract the uploads.tar.gz to your new single site installation
tar -xf /tmp/wp-bullet.com/guides.wp-bullet.com/uploads.tar.gz -C /var/www/guides.wp-bullet.com/wp-content/uploads/Fix permissions, if www-data isn’t the owner’s user and group change them to the correct values.
Remember to change your new single site installation path guides.wp-bullet.com
sudo chown -R www-data:www-data /var/www/guides.wp-bullet.com
sudo find /var/www/guides.wp-bullet.com -type f -exec chmod 644 {} +
sudo find /var/www/guides.wp-bullet.com -type d -exec chmod 755 {} +You can remove these tables using Adminer or phpMyAdmin, remember to adjust the database prefix if yours is not wp_
wp_blogs
wp_blog_versions
wp_registration_log
wp_signups
wp_site
wp_sitemeta
wp_sitecategories
You can also use WP-CLI to drop these tables with the wp db query command.
wp db query "DROP TABLE IF EXISTS wp_signups, wp_site, wp_sitemeta, wp_sitecategories, wp_registration_log, wp_blog_versions, wp_blogs;"That should do it!
Sources
tar Directory without Storing Absolute Paths
WP-CLI db tables command
Extracting Subsite from Multisite
Deleting Multiple MySQL Tables
10up Multisite Package