How to add drop-down menu in wordpress admin bar

I`m supporting several big multisite networks and yesterday one of my clients asked me to make a menu next to “My Sites”, which will have exactly the same structure but sites will be listed by domain instead of by site title. For those of you who still don`t get about which menu I`m talking about I`m attaching a screenshot. I spent some time searching for this solution so i decided to include it in our blog as a wordpress tutorial for our readers.

Wordpress backend admin menu

Yeah thats right…the horizontal admin bar at the top. I`ve written countless plugins before, so I thought “How hard can it be”. Turned out there is surprisingly little info on the subject so I decided to post this simple tutorial. The code I`m about to give you can be placed in your theme`s functions.php, can be packaged as a regular plugin or used as mu-plugin(my personal choice). Now let`s start coding…
First we need to find which is the action for the menu initialization and attach our function to it. When doing something similar the WordPress Codex is always a friend.  After I visited http://codex.wordpress.org/Plugin_API/Action_Reference I found out that the action I was looking for was called admin_menu (Duh…). So I started writing

function add_xn_admin_bar() {

}

add_action('admin_bar_menu', 'add_xn_admin_bar',25);

That way you tell WordPress to execute your function on admin menu initialization.

So…that was the harder part. Now i needed a menu title and target. In order to do that you have to use $wp_admin_bar (again..you can read all about it in the Codex http://codex.wordpress.org/Function_Reference/add_menu).

To add a menu item you write:

function add_xn_admin_bar() {

global $wp_admin_bar;

$wp_admin_bar->add_menu( array(
 'id' => 'xn_link',
 'title' => __( 'Sites by domain'),
 'href' => __('http://webbamboo.net/wp-admin'),
 ) );

}

add_action('admin_bar_menu', 'add_xn_admin_bar',25);

If you`ve done that properly you should already see the menu Sites by domain sitting next to My sites menu. In order to add a child element to the menu you use the “parent” attribute.

$wp_admin_bar->add_menu( array(
 'parent' => 'xn_link',
 'id' => $id,
 'title' => __($site_url->domain),
 'href' => __('http://'.$site_url->domain.'/'),
 ));

Enough details 🙂 I`ll add the code needed to make a menu that shows the sites in your multisite network not by title, but by domain name

<?php
/*
Plugin Name: Admin menu Sites by domain
Plugin URI: http://www.webbamboo.net
Description: Listing sites by domain.
Version: 1.0
Author: Pavel (aka Immortal) Petrov
Author URI: http://www.webbamboo.net
License: A "Slug" license name e.g. GPL2
*/

function add_xn_admin_bar() {
 global $wp_admin_bar;
if ( !is_super_admin() || !is_admin_bar_showing() )
 return;
 $wp_admin_bar->add_menu( array(
 'id' => 'xn_link',
 'title' => __( 'Sites by domain'),
 'href' => __('http://awordpress.net/wp-admin'),
 ) );

//Get the ids of all sites in your multisite network in an array()

global $wpdb;
 $blog_ids = $wpdb->get_col("SELECT `blog_id` FROM `wp_blogs` WHERE 1");

//Loop through the array to create a list with all the sites
 foreach($blog_ids as $id) {

//We don`t need the first one
 if($id != 1)
 {
 $site_url = $wpdb->get_row("SELECT `domain` FROM `wp_domain_mapping` WHERE `blog_id`='".$id."'");
 $wp_admin_bar->add_menu( array(
 'parent' => 'xn_link',
 'id' => $id,
 'title' => __($site_url->domain),
 'href' => __('http://'.$site_url->domain.'/'),
 ));

 $wp_admin_bar->add_menu( array(
 'parent' => $id,
 'id' => 'dashboard'.$id,
 'title' => __( 'Dashboard'),
 'href' => __('http://'.$site_url->domain.'/wp-admin/'),
 ));

 $wp_admin_bar->add_menu( array(
 'parent' => $id,
 'id' => 'post'.$id,
 'title' => __( 'New post'),
 'href' => __('http://'.$site_url->domain.'/wp-admin/post-new.php'),
 ));

 $wp_admin_bar->add_menu( array(
 'parent' => $id,
 'id' => 'visit'.$id,
 'title' => __( 'Visit site'),
 'href' => __('http://'.$site_url->domain.'/'),
 ));
 }
 }
}
add_action('admin_bar_menu', 'add_xn_admin_bar',25);

?>