Can I create one single menu that

  1. appears on every page within the network and

  2. contains every site and page that exists within the network?

I'm talking about the following structure:

  • Main Site

    • Sample Page 1
    • Sample Page 2

    • Network Site A

      • Sample Page A1
      • Sample Page A2
    • Network Site B

      • Sample Page B1

Is it possible to create a menu that looks like this?


get_sites() will get a list of the sites in a Multisite network. You can then use switch_to_blog()[*], get_posts() / get_pages(), and restore_current_blog()[*] to get the pages from the various sites.

I'd strongly recommend storing the results as a sitewide option using update_site_option() to lessen the load on your server. You could add a job to wp_cron() to update your option periodically, or add an action to the save_post (or one or more appropriate Post Status Transition hook(s), such as new_to_publish and draft_to_publish) to update your stored menu list. An added advantage to keeping the menu list in a site option is that you can access it from any site in your network using get_site_option().

[*] -- When Multisite originally came out, the terminology was a site of blogs; later it changed to a network of sites, but the old ways still appear in function names like switch_to_blog() and restore_current_blog().

| improve this answer | |
  • Phew... Could you help me out with a code snippet? I understand what you're saying but I don't feel capable of putting this together – okiedokey Jun 11 '14 at 7:07

There was a function called get_blog_list() which is currently deprecated due to the potential of high consumption if resources if a network has many sites. A better and less resource hungry way would be to query the wp_blogs table in your WP database using a custom query.

Add the following code to your theme's functions.php file and you should be good to go.

 * Build a list of all websites in a network
function wp_list_sites( $expires = 7200 ) {
   if( !is_multisite() ) return false;

   // Because the get_blog_list() function is currently flagged as deprecated 
   // due to the potential for high consumption of resources, we'll use
   // $wpdb to roll out our own SQL query instead. Because the query can be
   // memory-intensive, we'll store the results using the Transients API
   if ( false === ( $site_list = get_transient( 'multisite_site_list' ) ) ) {
      global $wpdb;
      $site_list = $wpdb->get_results( $wpdb->prepare('SELECT * FROM wp_blogs ORDER BY blog_id') );
      // Set the Transient cache to expire every two hours
      set_site_transient( 'multisite_site_list', $site_list, $expires );

   $current_site_url = get_site_url( get_current_blog_id() );

   $html = '' . "n";

   foreach ( $site_list as $site ) {
      switch_to_blog( $site->blog_id );
      $class = ( home_url() == $current_site_url ) ? ' class="current-site-item"' : '';
      $html .= "t" . 'blog_id . '"' . $class . '>' . get_bloginfo('name') . '' . "n";

   $html .= '' . "nn";

   return $html;
| improve this answer | |
  • There's a ' missing in line 21, should be $html .= "t" . 'blog_id' . '"' . $class . '>' . get_bloginfo('name') . '' . "n"; Thanks by the way! – okiedokey Jun 11 '14 at 6:54
  • Sorry for double posting but also, the $wpdb->prepare() function above produces a "missing argument" error – okiedokey Jun 11 '14 at 7:06

How about the Multi-Site Site List Shortcode plug-in? I used it in a text widget and it made the menu I was after. http://wordpress.org/plugins/multi-site-site-list-shortcode/

| improve this answer | |
  • Answers based only on external links without code or based only on third party software recomendations are bad answers. – cybmeta Jun 11 '14 at 21:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.