diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php
index 5464b61..acb0c1d 100644
--- a/src/wp-admin/includes/ms.php
+++ b/src/wp-admin/includes/ms.php
@@ -1028,3 +1028,110 @@
 </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_nav( $args = array() ) {
+
+	/**
+	 * Filter the links that appear on site-editing network pages
+	 *
+	 * Default tabs: 'site-info', 'site-users', 'site-themes', and 'site-settings'
+	 *
+	 * @since 4.6.0
+	 *
+	 * @param array Array of links
+	 */
+	$tabs = apply_filters( 'network_edit_site_links', array(
+		'site-info'     => array( 'label' => __( 'Info' ),     'url' => 'site-info.php',     'cap' => 'manage_sites' ),
+		'site-users'    => array( 'label' => __( 'Users' ),    'url' => 'site-users.php',    'cap' => 'manage_sites' ),
+		'site-themes'   => array( 'label' => __( 'Themes' ),   'url' => 'site-themes.php',   'cap' => 'manage_sites' ),
+		'site-settings' => array( 'label' => __( 'Settings' ), 'url' => 'site-settings.php', 'cap' => 'manage_sites' )
+	) );
+
+	// Parse arguments
+	$r = wp_parse_args( $args, array(
+		'blog_id'     => isset( $_GET['blog_id'] ) ? (int) $_GET['blog_id'] : 0,
+		'tabs'        => $tabs,
+		'selected'    => 'site-info',
+		'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_nav_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;
+		}
+
+		// Tab class and selected values
+		$classes  = array( 'nav-tab' );
+		$selected = 'false';
+		if (
+
+			// Selected is set by parent
+			( $r['selected'] === $tab_id )
+
+			||
+
+			// Selected is assumed by $pagenow global
+			( $tab['url'] === $GLOBALS['pagenow'] )
+		) {
+			$classes[] = 'nav-tab-active';
+			$selected  = 'true';
+		}
+
+		// Escape each class
+		$esc_classes = implode( ' ', array_map( 'esc_attr', $classes ) );
+
+		// 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 ) . '" id="' . esc_attr( $tab_id ) . '" class="' . $esc_classes . '">' . esc_html( $tab['label'] ) . '</a>';
+	}
+
+	// Start a buffer
+	ob_start();
+
+	// All done!
+	echo '<h2 class="nav-tab-wrapper wp-clearfix" role="tablist">';
+	echo implode( '', $r['screen_tabs'] );
+	echo '</h2>';
+
+	// Output the nav
+	echo ob_get_clean();
+}
diff --git a/src/wp-admin/network/site-info.php b/src/wp-admin/network/site-info.php
index b18d804..868e88c 100644
--- a/src/wp-admin/network/site-info.php
+++ b/src/wp-admin/network/site-info.php
@@ -143,21 +143,13 @@
 <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_nav( array(
+	'blog_id'  => $id,
+	'selected' => 'site-info'
+) );
+
 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..a5cdc6d 100644
--- a/src/wp-admin/network/site-settings.php
+++ b/src/wp-admin/network/site-settings.php
@@ -95,21 +95,14 @@
 <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_nav( array(
+	'blog_id'  => $id,
+	'selected' => 'site-settings'
+) );
+
 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..6d13fb2 100644
--- a/src/wp-admin/network/site-themes.php
+++ b/src/wp-admin/network/site-themes.php
@@ -149,20 +149,12 @@
 <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_nav( array(
+	'blog_id'  => $id,
+	'selected' => 'site-themes'
+) );
 
 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..cced8a4 100644
--- a/src/wp-admin/network/site-users.php
+++ b/src/wp-admin/network/site-users.php
@@ -204,20 +204,12 @@
 <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_nav( array(
+	'blog_id'  => $id,
+	'selected' => 'site-users'
+) );
 
 if ( isset($_GET['update']) ) :
 	switch($_GET['update']) {
