diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php
index 6e8fb07..1657da2 100644
--- a/src/wp-admin/includes/ms.php
+++ b/src/wp-admin/includes/ms.php
@@ -1124,3 +1124,102 @@
 </script>
 <?php
 }
+
+/**
+ * Output the HTML for a network's "Edit Site" tabular interface
+ *
+ * @since 4.6.0
+ *
+ * @link https://core.trac.wordpress.org/ticket/15800 discussion
+ *
+ * @param $args {
+ *     Optional. Array or string of Query parameters.
+ *
+ *     @type int          $blog_id     The site ID. Default is the current site.
+ *     @type string|array $before      The HTML to echo before the tabs
+ *     @type string|array $after       The HTML to echo after the tabs
+ *     @type array        $tabs        The tabs to include with (label|url|cap) keys
+ *     @type array        $screen_tabs Pre-rendered HTML tabs if you wish to own their output
+ * }
+ */
+function network_edit_site_tabs( $args = array() ) {
+	global $pagenow;
+
+	/**
+	 * Filter the tabs that appear on site-editing network pages
+	 *
+	 * Default tabs: 'site-info', 'site-users', 'site-themes', and 'site-settings'
+	 *
+	 * @since 4.6.0
+	 *
+	 * @param array         $search_columns Array of column names to be searched.
+	 * @param string        $search         Text being searched.
+	 * @param WP_User_Query $this           The current WP_User_Query instance.
+	 */
+	$tabs = apply_filters( 'network_edit_site_tabs', array(
+		'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php',     'cap' => 'manage_site_info'     ),
+		'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php',    'cap' => 'manage_site_users'    ),
+		'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php',   'cap' => 'manage_site_themes'   ),
+		'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php', 'cap' => 'manage_site_settings' )
+	) );
+
+	// Parse arguments
+	$r = wp_parse_args( $args, array(
+		'blog_id'     => 0,
+		'before'      => '<h2 class="nav-tab-wrapper wp-clearfix" role="tablist">',
+		'after'       => '</h2>',
+		'tabs'        => $tabs,
+		'screen_tabs' => array()
+	) );
+
+	/**
+	 * Filter the arguments used to output tabs that appear on site-editing network pages
+	 *
+	 * @since 4.6.0
+	 *
+	 * @param array $r    Parsed arguments
+	 * @param array $args Original arguments
+	 */
+	$r = apply_filters( 'network_edit_site_tabs_args', $r, $args );
+
+	// Loop through tabs
+	foreach ( $r['tabs'] as $tab_id => $tab ) {
+
+		// Skip tab if user can't access
+		if ( ! current_user_can( $tab['cap'], $r['blog_id'] ) ) {
+			continue;
+		}
+
+		// Skip if tab is pre-loaded
+		if ( isset( $r['screen_tabs'][ $tab_id ] ) ) {
+			continue;
+		}
+
+		// Is this tab active?
+		$class = ( $tab['url'] === $pagenow )
+			? ' nav-tab-active'
+			: '';
+
+		// Aria selected
+		$selected = ( $tab['url'] === $pagenow )
+			? 'true'
+			: 'false';
+
+		// Get the URL for this tab
+		$url = add_query_arg( array( 'id' => $r['blog_id'] ), network_admin_url( $tab['url'] ) );
+
+		// Add tab to screen tabs
+		$r['screen_tabs'][ $tab_id ] = '<a href="' . esc_url( $url ) . '" class="nav-tab' . esc_attr( $class ) . '" aria-controls="' . sanitize_title( $tab_id ) . '" aria-selected="' . esc_attr( $selected ) . '">' . esc_html( $tab['label'] ) . '</a>';
+	}
+
+	// Start a buffer
+	ob_start();
+
+	// All done!
+	echo $r['before'];
+	echo implode( '', $r['screen_tabs'] );
+	echo $r['after'];
+
+	// Put out the tabs
+	ob_end_flush();
+}
diff --git a/src/wp-admin/network/site-info.php b/src/wp-admin/network/site-info.php
index b18d804..e9e7b57 100644
--- a/src/wp-admin/network/site-info.php
+++ b/src/wp-admin/network/site-info.php
@@ -14,7 +14,7 @@
 	wp_die( __( 'Multisite support is not enabled.' ) );
 }
 
-if ( ! current_user_can( 'manage_sites' ) ) {
+if ( ! current_user_can( 'manage_site_info' ) ) {
 	wp_die( __( 'You do not have sufficient permissions to edit this site.' ) );
 }
 
@@ -143,21 +143,10 @@
 <div class="wrap">
 <h1 id="edit-site"><?php echo $title; ?></h1>
 <p class="edit-site-actions"><a href="<?php echo esc_url( get_home_url( $id, '/' ) ); ?>"><?php _e( 'Visit' ); ?></a> | <a href="<?php echo esc_url( get_admin_url( $id ) ); ?>"><?php _e( 'Dashboard' ); ?></a></p>
-<h2 class="nav-tab-wrapper nav-tab-small wp-clearfix">
 <?php
-$tabs = array(
-	'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php'     ),
-	'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php'    ),
-	'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php'   ),
-	'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php' ),
-);
-foreach ( $tabs as $tab_id => $tab ) {
-	$class = ( $tab['url'] == $pagenow ) ? ' nav-tab-active' : '';
-	echo '<a href="' . $tab['url'] . '?id=' . $id .'" class="nav-tab' . $class . '">' . esc_html( $tab['label'] ) . '</a>';
-}
-?>
-</h2>
-<?php
+
+network_edit_site_tabs( array( 'blog_id' => $id ) );
+
 if ( ! empty( $messages ) ) {
 	foreach ( $messages as $msg ) {
 		echo '<div id="message" class="updated notice is-dismissible"><p>' . $msg . '</p></div>';
diff --git a/src/wp-admin/network/site-settings.php b/src/wp-admin/network/site-settings.php
index b945ea7..86985a4 100644
--- a/src/wp-admin/network/site-settings.php
+++ b/src/wp-admin/network/site-settings.php
@@ -13,7 +13,7 @@
 if ( ! is_multisite() )
 	wp_die( __( 'Multisite support is not enabled.' ) );
 
-if ( ! current_user_can( 'manage_sites' ) )
+if ( ! current_user_can( 'manage_site_settings' ) )
 	wp_die( __( 'You do not have sufficient permissions to edit this site.' ) );
 
 get_current_screen()->add_help_tab( array(
@@ -95,21 +95,11 @@
 <div class="wrap">
 <h1 id="edit-site"><?php echo $title; ?></h1>
 <p class="edit-site-actions"><a href="<?php echo esc_url( get_home_url( $id, '/' ) ); ?>"><?php _e( 'Visit' ); ?></a> | <a href="<?php echo esc_url( get_admin_url( $id ) ); ?>"><?php _e( 'Dashboard' ); ?></a></p>
-<h2 class="nav-tab-wrapper nav-tab-small wp-clearfix">
+
 <?php
-$tabs = array(
-	'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php'     ),
-	'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php'    ),
-	'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php'   ),
-	'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php' ),
-);
-foreach ( $tabs as $tab_id => $tab ) {
-	$class = ( $tab['url'] == $pagenow ) ? ' nav-tab-active' : '';
-	echo '<a href="' . $tab['url'] . '?id=' . $id .'" class="nav-tab' . $class . '">' . esc_html( $tab['label'] ) . '</a>';
-}
-?>
-</h2>
-<?php
+
+network_edit_site_tabs( array( 'blog_id' => $id ) );
+
 if ( ! empty( $messages ) ) {
 	foreach ( $messages as $msg )
 		echo '<div id="message" class="updated notice is-dismissible"><p>' . $msg . '</p></div>';
diff --git a/src/wp-admin/network/site-themes.php b/src/wp-admin/network/site-themes.php
index d48e2ca..fadea0d 100644
--- a/src/wp-admin/network/site-themes.php
+++ b/src/wp-admin/network/site-themes.php
@@ -13,7 +13,7 @@
 if ( ! is_multisite() )
 	wp_die( __( 'Multisite support is not enabled.' ) );
 
-if ( ! current_user_can( 'manage_sites' ) )
+if ( ! current_user_can( 'manage_site_themes' ) )
 	wp_die( __( 'You do not have sufficient permissions to manage themes for this site.' ) );
 
 get_current_screen()->add_help_tab( array(
@@ -149,20 +149,9 @@
 <div class="wrap">
 <h1 id="edit-site"><?php echo $title; ?></h1>
 <p class="edit-site-actions"><a href="<?php echo esc_url( get_home_url( $id, '/' ) ); ?>"><?php _e( 'Visit' ); ?></a> | <a href="<?php echo esc_url( get_admin_url( $id ) ); ?>"><?php _e( 'Dashboard' ); ?></a></p>
-<h2 class="nav-tab-wrapper nav-tab-small wp-clearfix">
 <?php
-$tabs = array(
-	'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php'     ),
-	'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php'    ),
-	'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php'   ),
-	'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php' ),
-);
-foreach ( $tabs as $tab_id => $tab ) {
-	$class = ( $tab['url'] == $pagenow ) ? ' nav-tab-active' : '';
-	echo '<a href="' . $tab['url'] . '?id=' . $id .'" class="nav-tab' . $class . '">' . esc_html( $tab['label'] ) . '</a>';
-}
-?>
-</h2><?php
+
+network_edit_site_tabs( array( 'blog_id' => $id ) );
 
 if ( isset( $_GET['enabled'] ) ) {
 	$enabled = absint( $_GET['enabled'] );
diff --git a/src/wp-admin/network/site-users.php b/src/wp-admin/network/site-users.php
index 77122e8..922528b 100644
--- a/src/wp-admin/network/site-users.php
+++ b/src/wp-admin/network/site-users.php
@@ -13,7 +13,7 @@
 if ( ! is_multisite() )
 	wp_die( __( 'Multisite support is not enabled.' ) );
 
-if ( ! current_user_can('manage_sites') )
+if ( ! current_user_can( 'manage_site_users' ) )
 	wp_die(__('You do not have sufficient permissions to edit this site.'));
 
 $wp_list_table = _get_list_table('WP_Users_List_Table');
@@ -204,20 +204,9 @@
 <div class="wrap">
 <h1 id="edit-site"><?php echo $title; ?></h1>
 <p class="edit-site-actions"><a href="<?php echo esc_url( get_home_url( $id, '/' ) ); ?>"><?php _e( 'Visit' ); ?></a> | <a href="<?php echo esc_url( get_admin_url( $id ) ); ?>"><?php _e( 'Dashboard' ); ?></a></p>
-<h2 class="nav-tab-wrapper nav-tab-small wp-clearfix">
 <?php
-$tabs = array(
-	'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php'     ),
-	'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php'    ),
-	'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php'   ),
-	'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php' ),
-);
-foreach ( $tabs as $tab_id => $tab ) {
-	$class = ( $tab['url'] == $pagenow ) ? ' nav-tab-active' : '';
-	echo '<a href="' . $tab['url'] . '?id=' . $id .'" class="nav-tab' . $class . '">' . esc_html( $tab['label'] ) . '</a>';
-}
-?>
-</h2><?php
+
+network_edit_site_tabs( array( 'blog_id' => $id ) );
 
 if ( isset($_GET['update']) ) :
 	switch($_GET['update']) {
