John Russell Blog

Running a Development Copy of WordPress Multisite – Part 2

I recently made a detailed post explaining how I created a production and development environment that share a database using WordPress in a Multisite configuration.

One thing that I felt was missing from the production environment was the ability to quickly jump from production to development while making changes to site content. With the new WordPress adminbar it’s already easy to jump back and forth between the post/page and the dashboard, but I wanted a way to view the current site or current page in the development environment. So, I created a plugin that adds a menu to the WordPress adminbar that lists links to the development environment for the “Current Site”, “Current Page” (if a page is being viewed), and links to the homepage for each site within the WordPress Multisite network.

Since I will not likely ever enter this into the WordPress plugin repository I will simply post the code here. All you need to do is copy the following code into a text editor and save it as a php file and upload it into your production site’s plugin directory. Note that this will only work if you have created a production and development environment in accordance with my guide.

Plugin Name: Development Menu
Plugin URI:
Description: Adds WordPress Admin Bar menu items to link back to the development version of a site
Version: 0.0.1
Author: John Russell
Author URI:
License: GPLv2 or later

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

class DevelopmentMenu {

	function __construct() {
		if (defined('WP_DEVELOPMENT_DOMAIN')) add_action('admin_bar_menu', array($this, "development_links"));

	function add_root_menu($name, $id, $href = FALSE) {
		global $wp_admin_bar;
		if ( !is_super_admin() || !is_admin_bar_showing() )

		$wp_admin_bar->add_menu( array(
		    'id'   => $id,
		    'meta' => array(),
		    'title' => $name,
		    'href' => $href ) );

	function add_sub_menu($name, $link, $root_menu, $id, $meta = FALSE) {
		global $wp_admin_bar;
		if (!is_super_admin() || !is_admin_bar_showing()) return;

		$wp_admin_bar->add_menu( array(
		  'parent' => $root_menu,
		  'id' => $id,
		  'title' => $name,
		  'href' => $link,
		  'meta' => $meta
		) );

	function get_development_url($url) {
		// Takes in a URL with the production host and returns the same URL with the development host
		$url_components = parse_url($url);

		$return_value = $url_components['scheme'] . '://' . WP_DEVELOPMENT_DOMAIN . $url_components['path'];

		return $return_value;	

	function development_links() {
		$blog_details = get_blog_details();
		if (is_admin()) $screen = get_current_screen();

		$this->add_root_menu("Development Sites", "devrt");
		$this->add_sub_menu("Current Site", WP_DEVELOPMENT_DOMAIN . $blog_details->path, "devrt", "devcurrsite" );
		if (isset($screen) && $screen->base == 'post') {
			$this->add_sub_menu("Current Page", $this->get_development_url(get_permalink()), "devrt", "devcurrpage" );
		} elseif (!is_admin()) {
			if (is_main_site() || $_SERVER['HTTP_HOST'] == WP_PRODUCTION_DOMAIN) {
				// Current page link to development for main site or sites with no CNAME (using IP address)
				$this->add_sub_menu("Current Page", $this->get_development_url(stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']), "devrt", "devcurrpage" );
			} else {
				$this->add_sub_menu("Current Page", $this->get_development_url(stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . rtrim($blog_details->path, '/') . $_SERVER['REQUEST_URI']), "devrt", "devcurrpage" );
		// For Multisite
		if (is_multisite()) {
		    global $wpdb, $path;
		    $blog_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
		    foreach($blog_ids as $blog_id) {
		        $blog_details = get_blog_details($blog_id);
		        $this->add_sub_menu($blog_details->blogname, WP_DEVELOPMENT_DOMAIN . $blog_details->path, 'devrt', 'devblog'.$blog_id);

add_action("init", "DevelopmentMenuInit");
function DevelopmentMenuInit() {
    global $DevelopmentMenu;
    $DevelopmentMenu = new DevelopmentMenu();







Leave a Reply

Your email address will not be published. Required fields are marked *