Sharing is Caring: WordPress Multisite and Sharing Widgets

WordPress Multisite is a powerful way to manage a network of individual websites from one administration location. You can find plenty of articles about Multisite out there – when it’s appropriate to use it, how it works, how to configure it – but we recently found ourselves with a Multisite-related use case that proved difficult to solve, much like our other web design projects. We wanted to manage a particular widget area from the main site, and have the changes propagate to all of the sites on the network.

WordPress offers a nifty function called switch_to_blog() that can be used in similar situations (spoiler alert: it doesn’t work for widgets!). For example, you can use the following code in a theme or a plugin to display a menu that belongs to your main site:

switch_to_blog( 1 );
wp_nav_menu( $args );
restore_current_blog();

This function won’t work to load widgets because of how/when widget content is loaded. It doesn’t appear that there are any plans to change this.

So, what to do? We found surprisingly few write-ups about how to solve this problem, but there was a post from 2013 by WebDevStudios that started to lead us in the right direction. The solution proposed in their article didn’t work for us – the original author has written a few comment replies indicating that the solution is probably out-of-date. However, there was a more recent and simpler solution (no AJAX!) to be found in the comments.

With a few tweaks, our solution worked.

/**
* When sidebar is edited on main site, update sidebar on all subsites.
*/

// This is the function you use to place / call your sidebar at a specific theme location.
// Accepts the sidebar's id as a parameter.
function example_multisite_sidebar( $sidebar ) {

    // Try to get the stored widget content for the sidebar.
    $markup = get_site_transient( 'sidebar_cache_' . $sidebar );

    // If we're not on the main site and the transient exists, display the stored widget content.
    if (!is_main_site() && $markup ) {
        echo $markup;
    } else {
        // If we're not on the main site and the transient doesn't exist, we make a call to the main site, which kicks off example_multisite_sidebar_save().
        if (!is_main_site()) {
            $url = add_query_arg( array('get_sidebar' => $sidebar), get_site_url( 1 ) );
            $request = file_get_contents( $url );
            echo $request;

            // display the content
            echo get_site_transient( 'sidebar_cache_' . $sidebar );
        } else {
            // If we're on the main site and the transient doesn't exist, store the widget content in the transient.
            ob_start();
            dynamic_sidebar($sidebar);
            $markup = ob_get_clean();
            set_site_transient( 'sidebar_cache_' . $sidebar, $markup, 4*60*60 );
            echo $markup;
        }
    }
}

add_action( 'template_redirect', 'example_multisite_sidebar_save' );
function example_multisite_sidebar_save() {

    // If we're on the main site and the get_sidebar query var is set,
    // start a buffer that will record the widget content.
    if ( is_main_site() && isset( $_GET['get_sidebar'] ) ) {
        $sidebar = $_GET['get_sidebar'];
        ob_start();
        dynamic_sidebar( $sidebar );
        $markup = ob_get_clean();

        // Set a transient to store the HTML of the widget content
        set_site_transient( 'sidebar_cache_' . $sidebar, $markup, 4*60*60 );

        // Also display the content. This ensures that the content gets displayed if a site other than the main site is the first to be loaded after an update.
        echo $markup;

        die();
    }
}

// Delete all sidebar transients when editing sidebar widgets.
add_action( 'sidebar_admin_setup', 'example_multisite_sidebar_clear_cache' );
function example_multisite_sidebar_clear_cache() {
    global $wp_registered_sidebars;
    foreach($wp_registered_sidebars as $sidebar){
        delete_site_transient('sidebar_cache_' . $sidebar['id']);
    }
}

With this code, we’re able to update a widget on the main site, and then immediately see the changes on any of the network sites. If you’ve got a suggestion for improvement, we’d love to hear it! Drop us a line on Twitter.

Don't Branch Out Alone

We know that your time is limited but taking your website to the next level is essential. Don’t branch out alone. Tap into our team of experts to keep your site ahead of the curve.

Let Us Help

Share

Similar Posts
Also tagged Wordpress

10 Best WordPress LMS Options: What to Look For

Also tagged SEO

Technical SEO vs Content SEO

Also tagged SEO

Web Page Elements 5 Focus Areas