Site Health: Support custom sub-menus and pages.

Allow developers to extend the Site Health screen with their own custom navigation tabs and pages.

This implements a new filter, `site_health_navigation_tabs`, which takes an associated array of tab identifiers/slugs, and tab labels, allowing developers to add their own subpage to the Site Health interface as new tabs.

To output a custom page, or add to an existing page, the `site_health_tab_content` action is triggered whenever the `tab` query argument is present and not empty. This action includes the current tab as its argument, which a developer would match against to only output content when relevant.

Props ramiy for initial patch.
Fixes #47225.
Built from https://develop.svn.wordpress.org/trunk@50764


git-svn-id: http://core.svn.wordpress.org/trunk@50373 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Clorith 2021-04-17 01:14:01 +00:00
parent b4fac1593d
commit eea98a5426
10 changed files with 238 additions and 79 deletions

View File

@ -119,12 +119,22 @@
.health-check-tabs-wrapper { .health-check-tabs-wrapper {
/* IE 11 */ /* IE 11 */
display: -ms-inline-grid; display: -ms-inline-grid;
-ms-grid-columns: 1fr 1fr; -ms-grid-columns: 1fr 1fr 1fr 1fr;
vertical-align: top; vertical-align: top;
/* modern browsers */ /* modern browsers */
display: inline-grid; display: inline-grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
.health-check-tabs-wrapper.tab-count-1 {
grid-template-columns: 1fr;
}
.health-check-tabs-wrapper.tab-count-2 {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
} }
.health-check-tabs-wrapper.tab-count-3 {
grid-template-columns: 1fr 1fr 1fr;
}
.health-check-tab { .health-check-tab {
display: block; /* IE 11 */ display: block; /* IE 11 */
@ -135,6 +145,43 @@
transition: box-shadow 0.5s ease-in-out; transition: box-shadow 0.5s ease-in-out;
} }
.health-check-offscreen-nav-wrapper {
position: relative;
background: transparent;
border: none;
}
.health-check-offscreen-nav-wrapper:focus .health-check-offscreen-nav {
right: initial;
}
.health-check-offscreen-nav {
display: none;
position: absolute;
padding-top: 10px;
left: 0;
top: 100%;
width: 13rem;
}
.health-check-offscreen-nav-wrapper.visible .health-check-offscreen-nav {
display: inline-block;
}
.health-check-offscreen-nav:before {
position: absolute;
content: "";
width: 0;
height: 0;
border-style: solid;
border-width: 0 10px 5px 10px;
border-color: transparent transparent #ffffff transparent;
left: 20px;
top: 5px;
}
.health-check-offscreen-nav .health-check-tab {
background: #fff;
box-shadow: 0 2px 5px 0 rgba( 0, 0, 0, 0.75 );
}
.health-check-tab:nth-child(1) { .health-check-tab:nth-child(1) {
-ms-grid-column: 1; /* IE 11 */ -ms-grid-column: 1; /* IE 11 */
} }
@ -153,6 +200,10 @@
box-shadow: inset 0 -3px #3582c4; box-shadow: inset 0 -3px #3582c4;
font-weight: 600; font-weight: 600;
} }
.health-check-offscreen-nav .health-check-tab.active {
box-shadow: inset -3px 0 #3582c4;
font-weight: 600;
}
.health-check-body { .health-check-body {
max-width: 800px; max-width: 800px;

File diff suppressed because one or more lines are too long

View File

@ -118,12 +118,22 @@
.health-check-tabs-wrapper { .health-check-tabs-wrapper {
/* IE 11 */ /* IE 11 */
display: -ms-inline-grid; display: -ms-inline-grid;
-ms-grid-columns: 1fr 1fr; -ms-grid-columns: 1fr 1fr 1fr 1fr;
vertical-align: top; vertical-align: top;
/* modern browsers */ /* modern browsers */
display: inline-grid; display: inline-grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
.health-check-tabs-wrapper.tab-count-1 {
grid-template-columns: 1fr;
}
.health-check-tabs-wrapper.tab-count-2 {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
} }
.health-check-tabs-wrapper.tab-count-3 {
grid-template-columns: 1fr 1fr 1fr;
}
.health-check-tab { .health-check-tab {
display: block; /* IE 11 */ display: block; /* IE 11 */
@ -134,6 +144,43 @@
transition: box-shadow 0.5s ease-in-out; transition: box-shadow 0.5s ease-in-out;
} }
.health-check-offscreen-nav-wrapper {
position: relative;
background: transparent;
border: none;
}
.health-check-offscreen-nav-wrapper:focus .health-check-offscreen-nav {
left: initial;
}
.health-check-offscreen-nav {
display: none;
position: absolute;
padding-top: 10px;
right: 0;
top: 100%;
width: 13rem;
}
.health-check-offscreen-nav-wrapper.visible .health-check-offscreen-nav {
display: inline-block;
}
.health-check-offscreen-nav:before {
position: absolute;
content: "";
width: 0;
height: 0;
border-style: solid;
border-width: 0 10px 5px 10px;
border-color: transparent transparent #ffffff transparent;
right: 20px;
top: 5px;
}
.health-check-offscreen-nav .health-check-tab {
background: #fff;
box-shadow: 0 2px 5px 0 rgba( 0, 0, 0, 0.75 );
}
.health-check-tab:nth-child(1) { .health-check-tab:nth-child(1) {
-ms-grid-column: 1; /* IE 11 */ -ms-grid-column: 1; /* IE 11 */
} }
@ -152,6 +199,10 @@
box-shadow: inset 0 -3px #3582c4; box-shadow: inset 0 -3px #3582c4;
font-weight: 600; font-weight: 600;
} }
.health-check-offscreen-nav .health-check-tab.active {
box-shadow: inset 3px 0 #3582c4;
font-weight: 600;
}
.health-check-body { .health-check-body {
max-width: 800px; max-width: 800px;

File diff suppressed because one or more lines are too long

View File

@ -50,6 +50,21 @@ class WP_Site_Health {
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action( 'wp_site_health_scheduled_check', array( $this, 'wp_cron_scheduled_check' ) ); add_action( 'wp_site_health_scheduled_check', array( $this, 'wp_cron_scheduled_check' ) );
add_action( 'site_health_tab_content', array( $this, 'show_site_health_tab' ) );
}
/**
* Output the content of a tab in the Site Health screen.
*
* @since 5.8.0
*
* @param string $tab Slug of the current tab being displayed.
*/
public function show_site_health_tab( $tab ) {
if ( 'debug' === $tab ) {
require_once ABSPATH . '/wp-admin/site-health-info.php';
}
} }
/** /**
@ -103,7 +118,7 @@ class WP_Site_Health {
$health_check_js_variables['site_status']['issues'] = $issue_counts; $health_check_js_variables['site_status']['issues'] = $issue_counts;
} }
if ( 'site-health' === $screen->id && ! isset( $_GET['tab'] ) ) { if ( 'site-health' === $screen->id && ( ! isset( $_GET['tab'] ) || empty( $_GET['tab'] ) ) ) {
$tests = WP_Site_Health::get_tests(); $tests = WP_Site_Health::get_tests();
// Don't run https test on development environments. // Don't run https test on development environments.

View File

@ -443,4 +443,9 @@ jQuery( function( $ ) {
recalculateProgression(); recalculateProgression();
} }
} }
// Trigger a class toggle when the extended menu button is clicked.
$( '.health-check-offscreen-nav-wrapper' ).on( 'click', function() {
$( this ).toggleClass( 'visible' );
} );
} ); } );

File diff suppressed because one or more lines are too long

View File

@ -6,18 +6,10 @@
* @subpackage Administration * @subpackage Administration
*/ */
/** WordPress Administration Bootstrap */ if ( ! defined( 'ABSPATH' ) ) {
require_once __DIR__ . '/admin.php'; die();
$title = __( 'Site Health Info' );
if ( ! current_user_can( 'view_site_health_checks' ) ) {
wp_die( __( 'Sorry, you are not allowed to access the debug data.' ), '', 403 );
} }
wp_enqueue_style( 'site-health' );
wp_enqueue_script( 'site-health' );
if ( ! class_exists( 'WP_Debug_Data' ) ) { if ( ! class_exists( 'WP_Debug_Data' ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
} }
@ -26,46 +18,7 @@ if ( ! class_exists( 'WP_Site_Health' ) ) {
} }
$health_check_site_status = WP_Site_Health::get_instance(); $health_check_site_status = WP_Site_Health::get_instance();
require_once ABSPATH . 'wp-admin/admin-header.php';
?> ?>
<div class="health-check-header">
<div class="health-check-title-section">
<h1>
<?php _e( 'Site Health' ); ?>
</h1>
</div>
<div class="health-check-title-section site-health-progress-wrapper loading hide-if-no-js">
<div class="site-health-progress">
<svg role="img" aria-hidden="true" focusable="false" width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
<circle id="bar" r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
</svg>
</div>
<div class="site-health-progress-label">
<?php _e( 'Results are still loading&hellip;' ); ?>
</div>
</div>
<nav class="health-check-tabs-wrapper hide-if-no-js" aria-label="<?php esc_attr_e( 'Secondary menu' ); ?>">
<a href="<?php echo esc_url( admin_url( 'site-health.php' ) ); ?>" class="health-check-tab">
<?php
/* translators: Tab heading for Site Health Status page. */
_ex( 'Status', 'Site Health' );
?>
</a>
<a href="<?php echo esc_url( admin_url( 'site-health.php?tab=debug' ) ); ?>" class="health-check-tab active" aria-current="true">
<?php
/* translators: Tab heading for Site Health Info page. */
_ex( 'Info', 'Site Health' );
?>
</a>
</nav>
</div>
<hr class="wp-header-end">
<div class="notice notice-error hide-if-js"> <div class="notice notice-error hide-if-js">
<p><?php _e( 'The Site Health check requires JavaScript.' ); ?></p> <p><?php _e( 'The Site Health check requires JavaScript.' ); ?></p>
@ -179,6 +132,3 @@ require_once ABSPATH . 'wp-admin/admin-header.php';
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
<?php
require_once ABSPATH . 'wp-admin/admin-footer.php';

View File

@ -6,17 +6,41 @@
* @subpackage Administration * @subpackage Administration
*/ */
if ( isset( $_GET['tab'] ) && 'debug' === $_GET['tab'] ) {
require_once __DIR__ . '/site-health-info.php';
return;
}
/** WordPress Administration Bootstrap */ /** WordPress Administration Bootstrap */
require_once __DIR__ . '/admin.php'; require_once __DIR__ . '/admin.php';
wp_reset_vars( array( 'action' ) ); wp_reset_vars( array( 'action' ) );
$title = __( 'Site Health Status' ); $tabs = array(
/* translators: Tab heading for Site Health Status page. */
'' => _x( 'Status', 'Site Health' ),
/* translators: Tab heading for Site Health Info page. */
'debug' => _x( 'Info', 'Site Health' ),
);
/**
* An associated array of extra tabs for the Site Health navigation bar.
*
* Add a custom page to the Site Health screen, based on a tab slug and label.
* The label you provide will also be used as part of the site title.
*
* @since 5.8.0
*
* @param array $tabs An associated array of tab slugs and their label.
*/
$tabs = apply_filters( 'site_health_navigation_tabs', $tabs );
$wrapper_classes = array(
'health-check-tabs-wrapper',
'hide-if-no-js',
'tab-count-' . count( $tabs ),
);
$title = sprintf(
// translators: %s: The currently displayed tab.
__( 'Site Health %s' ),
( isset( $_GET['tab'] ) ? esc_html( $tabs[ $_GET['tab'] ] ) : esc_html( $tabs[0] ) )
);
if ( ! current_user_can( 'view_site_health_checks' ) ) { if ( ! current_user_can( 'view_site_health_checks' ) ) {
wp_die( __( 'Sorry, you are not allowed to access site health information.' ), '', 403 ); wp_die( __( 'Sorry, you are not allowed to access site health information.' ), '', 403 );
@ -86,25 +110,87 @@ require_once ABSPATH . 'wp-admin/admin-header.php';
</div> </div>
</div> </div>
<nav class="health-check-tabs-wrapper hide-if-no-js" aria-label="<?php esc_attr_e( 'Secondary menu' ); ?>"> <nav class="<?php echo implode( ' ', $wrapper_classes ); ?>" aria-label="<?php esc_attr_e( 'Secondary menu' ); ?>">
<a href="<?php echo esc_url( admin_url( 'site-health.php' ) ); ?>" class="health-check-tab active" aria-current="true"> <?php
<?php $tabs_slice = $tabs;
/* translators: Tab heading for Site Health Status page. */
_ex( 'Status', 'Site Health' );
?>
</a>
<a href="<?php echo esc_url( admin_url( 'site-health.php?tab=debug' ) ); ?>" class="health-check-tab"> /*
<?php * If there are more than 4 tabs, only output the first 3 inline,
/* translators: Tab heading for Site Health Info page. */ * the remaining links will be added to a sub-navigation.
_ex( 'Info', 'Site Health' ); */
?> if ( count( $tabs ) > 4 ) {
</a> $tabs_slice = array_slice( $tabs, 0, 3 );
}
foreach ( $tabs_slice as $slug => $label ) {
printf(
'<a href="%s" class="health-check-tab %s">%s</a>',
esc_url(
add_query_arg(
array(
'tab' => $slug,
),
admin_url( 'site-health.php' )
)
),
( isset( $_GET['tab'] ) && $_GET['tab'] === $slug ? 'active' : '' ),
esc_html( $label )
);
}
?>
<?php if ( count( $tabs ) > 4 ) : ?>
<button type="button" class="health-check-tab health-check-offscreen-nav-wrapper" aria-haspopup="true">
<span class="dashicons dashicons-ellipsis"></span>
<span class="screen-reader-text"><?php _e( 'Toggle extra menu items' ); ?></span>
<div class="health-check-offscreen-nav">
<?php
// Remove the first few entries from the array as being already output.
$tabs_slice = array_slice( $tabs, 3 );
foreach ( $tabs_slice as $slug => $label ) {
printf(
'<a href="%s" class="health-check-tab %s">%s</a>',
esc_url(
add_query_arg(
array(
'tab' => $slug,
),
admin_url( 'site-health.php' )
)
),
( isset( $_GET['tab'] ) && $_GET['tab'] === $slug ? 'active' : '' ),
esc_html( $label )
);
}
?>
</div>
</button>
<?php endif; ?>
</nav> </nav>
</div> </div>
<hr class="wp-header-end"> <hr class="wp-header-end">
<?php
if ( isset( $_GET['tab'] ) && ! empty( $_GET['tab'] ) ) {
/**
* Output content of a custom Site Health tab.
*
* This action fires right after the Site Health header, and users are still subject to
* the capability checks for the Site Health page to view any custom tabs and their contents.
*
* @since 5.8.0
*
* @param string $tab The slug of the tab that was requested.
*/
do_action( 'site_health_tab_content', $_GET['tab'] );
require_once ABSPATH . 'wp-admin/admin-footer.php';
return;
} else {
?>
<div class="notice notice-error hide-if-js"> <div class="notice notice-error hide-if-js">
<p><?php _e( 'The Site Health check requires JavaScript.' ); ?></p> <p><?php _e( 'The Site Health check requires JavaScript.' ); ?></p>
</div> </div>
@ -193,5 +279,6 @@ require_once ABSPATH . 'wp-admin/admin-header.php';
</div> </div>
</script> </script>
<?php <?php
}
require_once ABSPATH . 'wp-admin/admin-footer.php'; require_once ABSPATH . 'wp-admin/admin-footer.php';

View File

@ -13,7 +13,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '5.8-alpha-50763'; $wp_version = '5.8-alpha-50764';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.