I’ll build this as a full theme admin dashboard widgets module: site overview, theme status, performance hints, security checks, quick links, system info, recent content, and optional admin notices.
Below is a large advanced inc/admin/dashboard-widgets.php file for your RX Theme. It adds many useful WordPress admin dashboard widgets: theme status, site overview, performance, security, SEO, recent content, system info, quick actions, cleanup links, and developer notes.
Create this file:
rx-theme/inc/admin/dashboard-widgets.php
Then paste this full code:
<?php
/**
* RX Theme - Advanced Admin Dashboard Widgets
*
* File: inc/admin/dashboard-widgets.php
*
* Adds professional custom dashboard widgets for the RX Theme:
* - RX Theme Overview
* - Site Health Summary
* - SEO Status
* - Performance Checks
* - Security Checks
* - Recent Content
* - Quick Admin Actions
* - Server/System Info
* - Developer Notes
*
* @package RX_Theme
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'RX_Theme_Dashboard_Widgets' ) ) :
final class RX_Theme_Dashboard_Widgets {
/**
* Capability required to view RX dashboard widgets.
*
* @var string
*/
private static $capability = 'manage_options';
/**
* Initialize hooks.
*/
public static function init() {
add_action( 'wp_dashboard_setup', array( __CLASS__, 'register_dashboard_widgets' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_admin_assets' ) );
add_action( 'admin_init', array( __CLASS__, 'handle_quick_actions' ) );
add_action( 'wp_ajax_rx_theme_clear_dashboard_cache', array( __CLASS__, 'ajax_clear_dashboard_cache' ) );
add_filter( 'dashboard_glance_items', array( __CLASS__, 'add_glance_items' ) );
}
/**
* Register all dashboard widgets.
*/
public static function register_dashboard_widgets() {
if ( ! current_user_can( self::$capability ) ) {
return;
}
wp_add_dashboard_widget(
'rx_theme_overview_widget',
esc_html__( 'RX Theme Overview', 'rx-theme' ),
array( __CLASS__, 'render_theme_overview_widget' )
);
wp_add_dashboard_widget(
'rx_site_health_widget',
esc_html__( 'RX Site Health Summary', 'rx-theme' ),
array( __CLASS__, 'render_site_health_widget' )
);
wp_add_dashboard_widget(
'rx_seo_status_widget',
esc_html__( 'RX SEO Status', 'rx-theme' ),
array( __CLASS__, 'render_seo_status_widget' )
);
wp_add_dashboard_widget(
'rx_performance_widget',
esc_html__( 'RX Performance Checks', 'rx-theme' ),
array( __CLASS__, 'render_performance_widget' )
);
wp_add_dashboard_widget(
'rx_security_widget',
esc_html__( 'RX Security Checks', 'rx-theme' ),
array( __CLASS__, 'render_security_widget' )
);
wp_add_dashboard_widget(
'rx_recent_content_widget',
esc_html__( 'RX Recent Content', 'rx-theme' ),
array( __CLASS__, 'render_recent_content_widget' )
);
wp_add_dashboard_widget(
'rx_quick_actions_widget',
esc_html__( 'RX Quick Actions', 'rx-theme' ),
array( __CLASS__, 'render_quick_actions_widget' )
);
wp_add_dashboard_widget(
'rx_system_info_widget',
esc_html__( 'RX System Information', 'rx-theme' ),
array( __CLASS__, 'render_system_info_widget' )
);
wp_add_dashboard_widget(
'rx_developer_notes_widget',
esc_html__( 'RX Developer Notes', 'rx-theme' ),
array( __CLASS__, 'render_developer_notes_widget' )
);
}
/**
* Admin CSS and JavaScript.
*/
public static function enqueue_admin_assets( $hook ) {
if ( 'index.php' !== $hook ) {
return;
}
$css = '
.rx-dashboard-wrap {
font-size: 13px;
line-height: 1.6;
}
.rx-dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
margin-top: 10px;
}
.rx-dashboard-card {
background: #fff;
border: 1px solid #dcdcde;
border-radius: 8px;
padding: 12px;
}
.rx-dashboard-card h4 {
margin: 0 0 6px;
font-size: 13px;
}
.rx-dashboard-value {
font-size: 22px;
font-weight: 700;
margin: 3px 0;
}
.rx-status {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 3px 8px;
border-radius: 999px;
font-size: 12px;
font-weight: 600;
}
.rx-status-good {
background: #edfaef;
color: #0a6b22;
}
.rx-status-warning {
background: #fff8e5;
color: #8a5a00;
}
.rx-status-danger {
background: #fdecec;
color: #9d1c1c;
}
.rx-status-info {
background: #eef6ff;
color: #005a9e;
}
.rx-dashboard-list {
margin: 10px 0 0;
}
.rx-dashboard-list li {
display: flex;
justify-content: space-between;
gap: 10px;
border-bottom: 1px solid #f0f0f1;
padding: 7px 0;
margin: 0;
}
.rx-dashboard-list li:last-child {
border-bottom: 0;
}
.rx-dashboard-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
}
.rx-dashboard-actions .button {
margin: 0;
}
.rx-muted {
color: #646970;
}
.rx-small {
font-size: 12px;
}
.rx-code {
font-family: Consolas, Monaco, monospace;
background: #f6f7f7;
border: 1px solid #dcdcde;
padding: 2px 5px;
border-radius: 4px;
}
.rx-progress {
height: 8px;
background: #f0f0f1;
border-radius: 20px;
overflow: hidden;
margin-top: 6px;
}
.rx-progress span {
display: block;
height: 100%;
background: #2271b1;
}
';
wp_register_style( 'rx-dashboard-widgets', false, array(), self::theme_version() );
wp_enqueue_style( 'rx-dashboard-widgets' );
wp_add_inline_style( 'rx-dashboard-widgets', $css );
$js = '
(function($){
$(document).on("click", ".rx-clear-dashboard-cache", function(e){
e.preventDefault();
var $button = $(this);
var oldText = $button.text();
$button.text("Clearing...").prop("disabled", true);
$.post(ajaxurl, {
action: "rx_theme_clear_dashboard_cache",
nonce: $button.data("nonce")
}).done(function(response){
if (response && response.success) {
$button.text("Cache Cleared");
setTimeout(function(){ location.reload(); }, 700);
} else {
$button.text("Failed");
}
}).fail(function(){
$button.text("Failed");
}).always(function(){
setTimeout(function(){
$button.text(oldText).prop("disabled", false);
}, 1500);
});
});
})(jQuery);
';
wp_register_script( 'rx-dashboard-widgets', false, array( 'jquery' ), self::theme_version(), true );
wp_enqueue_script( 'rx-dashboard-widgets' );
wp_add_inline_script( 'rx-dashboard-widgets', $js );
}
/**
* RX Theme Overview Widget.
*/
public static function render_theme_overview_widget() {
$theme = wp_get_theme();
$child_theme = is_child_theme();
$theme_name = $theme->get( 'Name' );
$theme_ver = $theme->get( 'Version' );
$theme_author = $theme->get( 'Author' );
?>
<div class="rx-dashboard-wrap">
<p>
<strong><?php echo esc_html( $theme_name ); ?></strong>
<span class="rx-muted">v<?php echo esc_html( $theme_ver ? $theme_ver : '1.0.0' ); ?></span>
</p>
<div class="rx-dashboard-grid">
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'Theme Mode', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo $child_theme ? esc_html__( 'Child', 'rx-theme' ) : esc_html__( 'Parent', 'rx-theme' ); ?></div>
</div>
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'WordPress', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( get_bloginfo( 'version' ) ); ?></div>
</div>
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'PHP', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( PHP_VERSION ); ?></div>
</div>
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'Environment', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( wp_get_environment_type() ); ?></div>
</div>
</div>
<ul class="rx-dashboard-list">
<li>
<span><?php esc_html_e( 'Theme Author', 'rx-theme' ); ?></span>
<strong><?php echo wp_kses_post( $theme_author ? $theme_author : 'RX Theme' ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Stylesheet Directory', 'rx-theme' ); ?></span>
<span class="rx-code"><?php echo esc_html( basename( get_stylesheet_directory() ) ); ?></span>
</li>
<li>
<span><?php esc_html_e( 'Template Directory', 'rx-theme' ); ?></span>
<span class="rx-code"><?php echo esc_html( basename( get_template_directory() ) ); ?></span>
</li>
</ul>
<div class="rx-dashboard-actions">
<a class="button button-primary" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>">
<?php esc_html_e( 'Customize Theme', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'themes.php' ) ); ?>">
<?php esc_html_e( 'Manage Themes', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'nav-menus.php' ) ); ?>">
<?php esc_html_e( 'Menus', 'rx-theme' ); ?>
</a>
</div>
</div>
<?php
}
/**
* Site Health Summary Widget.
*/
public static function render_site_health_widget() {
$post_count = wp_count_posts( 'post' );
$page_count = wp_count_posts( 'page' );
$comment_count = wp_count_comments();
$plugin_count = self::get_plugin_count();
$active_theme = wp_get_theme();
$public_site = (int) get_option( 'blog_public', 1 );
$timezone = wp_timezone_string();
$permalink = get_option( 'permalink_structure' );
?>
<div class="rx-dashboard-wrap">
<div class="rx-dashboard-grid">
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'Published Posts', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( number_format_i18n( (int) $post_count->publish ) ); ?></div>
</div>
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'Published Pages', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( number_format_i18n( (int) $page_count->publish ) ); ?></div>
</div>
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'Approved Comments', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( number_format_i18n( (int) $comment_count->approved ) ); ?></div>
</div>
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'Active Plugins', 'rx-theme' ); ?></h4>
<div class="rx-dashboard-value"><?php echo esc_html( number_format_i18n( $plugin_count['active'] ) ); ?></div>
</div>
</div>
<ul class="rx-dashboard-list">
<li>
<span><?php esc_html_e( 'Search Engine Visibility', 'rx-theme' ); ?></span>
<?php echo $public_site ? self::status_badge( 'good', __( 'Visible', 'rx-theme' ) ) : self::status_badge( 'danger', __( 'Discouraged', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Permalink Structure', 'rx-theme' ); ?></span>
<?php echo $permalink ? self::status_badge( 'good', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Plain', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Timezone', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $timezone ? $timezone : 'UTC' ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Current Theme', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $active_theme->get( 'Name' ) ); ?></strong>
</li>
</ul>
<div class="rx-dashboard-actions">
<a class="button" href="<?php echo esc_url( admin_url( 'site-health.php' ) ); ?>">
<?php esc_html_e( 'Open Site Health', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'options-permalink.php' ) ); ?>">
<?php esc_html_e( 'Permalinks', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'options-reading.php' ) ); ?>">
<?php esc_html_e( 'Reading Settings', 'rx-theme' ); ?>
</a>
</div>
</div>
<?php
}
/**
* SEO Status Widget.
*/
public static function render_seo_status_widget() {
$blog_public = (int) get_option( 'blog_public', 1 );
$site_title = get_bloginfo( 'name' );
$tagline = get_bloginfo( 'description' );
$permalink = get_option( 'permalink_structure' );
$front_page_id = (int) get_option( 'page_on_front' );
$show_on_front = get_option( 'show_on_front' );
$robots_file = ABSPATH . 'robots.txt';
$sitemap_enabled = function_exists( 'wp_sitemaps_get_server' );
?>
<div class="rx-dashboard-wrap">
<ul class="rx-dashboard-list">
<li>
<span><?php esc_html_e( 'Search Engine Indexing', 'rx-theme' ); ?></span>
<?php echo $blog_public ? self::status_badge( 'good', __( 'Allowed', 'rx-theme' ) ) : self::status_badge( 'danger', __( 'Blocked', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Site Title', 'rx-theme' ); ?></span>
<?php echo ! empty( $site_title ) ? self::status_badge( 'good', __( 'Set', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Missing', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Tagline', 'rx-theme' ); ?></span>
<?php echo ! empty( $tagline ) ? self::status_badge( 'good', __( 'Set', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Missing', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'SEO-Friendly Permalinks', 'rx-theme' ); ?></span>
<?php echo ! empty( $permalink ) ? self::status_badge( 'good', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Plain URL', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Static Homepage', 'rx-theme' ); ?></span>
<?php echo ( 'page' === $show_on_front && $front_page_id ) ? self::status_badge( 'good', __( 'Configured', 'rx-theme' ) ) : self::status_badge( 'info', __( 'Blog Feed', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'WordPress Sitemap', 'rx-theme' ); ?></span>
<?php echo $sitemap_enabled ? self::status_badge( 'good', __( 'Available', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Unavailable', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Robots.txt File', 'rx-theme' ); ?></span>
<?php echo file_exists( $robots_file ) ? self::status_badge( 'good', __( 'Physical File', 'rx-theme' ) ) : self::status_badge( 'info', __( 'Virtual Default', 'rx-theme' ) ); ?>
</li>
</ul>
<div class="rx-dashboard-actions">
<a class="button" href="<?php echo esc_url( home_url( '/wp-sitemap.xml' ) ); ?>" target="_blank" rel="noopener">
<?php esc_html_e( 'View Sitemap', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( home_url( '/robots.txt' ) ); ?>" target="_blank" rel="noopener">
<?php esc_html_e( 'View Robots.txt', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'options-general.php' ) ); ?>">
<?php esc_html_e( 'General Settings', 'rx-theme' ); ?>
</a>
</div>
</div>
<?php
}
/**
* Performance Widget.
*/
public static function render_performance_widget() {
$memory_limit = wp_convert_hr_to_bytes( WP_MEMORY_LIMIT );
$memory_limit_mb = $memory_limit ? round( $memory_limit / MB_IN_BYTES ) : 0;
$memory_usage = function_exists( 'memory_get_usage' ) ? memory_get_usage( true ) : 0;
$memory_usage_mb = $memory_usage ? round( $memory_usage / MB_IN_BYTES ) : 0;
$memory_percent = ( $memory_limit > 0 && $memory_usage > 0 ) ? min( 100, round( ( $memory_usage / $memory_limit ) * 100 ) ) : 0;
$object_cache = wp_using_ext_object_cache();
$gzip_possible = extension_loaded( 'zlib' );
$opcache_enabled = function_exists( 'opcache_get_status' ) ? (bool) opcache_get_status( false ) : false;
$uploads = wp_upload_dir();
$uploads_writable = ! empty( $uploads['basedir'] ) && wp_is_writable( $uploads['basedir'] );
?>
<div class="rx-dashboard-wrap">
<div class="rx-dashboard-card">
<h4><?php esc_html_e( 'PHP Memory Usage', 'rx-theme' ); ?></h4>
<strong>
<?php
echo esc_html(
sprintf(
/* translators: 1: usage, 2: limit */
__( '%1$s MB of %2$s MB', 'rx-theme' ),
$memory_usage_mb,
$memory_limit_mb
)
);
?>
</strong>
<div class="rx-progress">
<span style="width: <?php echo esc_attr( $memory_percent ); ?>%;"></span>
</div>
<p class="rx-muted rx-small">
<?php esc_html_e( 'Lower memory usage usually means faster admin loading.', 'rx-theme' ); ?>
</p>
</div>
<ul class="rx-dashboard-list">
<li>
<span><?php esc_html_e( 'External Object Cache', 'rx-theme' ); ?></span>
<?php echo $object_cache ? self::status_badge( 'good', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'info', __( 'Not Detected', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'GZIP/Zlib Extension', 'rx-theme' ); ?></span>
<?php echo $gzip_possible ? self::status_badge( 'good', __( 'Available', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Missing', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'OPcache', 'rx-theme' ); ?></span>
<?php echo $opcache_enabled ? self::status_badge( 'good', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'info', __( 'Not Detected', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Uploads Folder Writable', 'rx-theme' ); ?></span>
<?php echo $uploads_writable ? self::status_badge( 'good', __( 'Writable', 'rx-theme' ) ) : self::status_badge( 'danger', __( 'Not Writable', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Script Debug Mode', 'rx-theme' ); ?></span>
<?php echo ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? self::status_badge( 'warning', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'good', __( 'Disabled', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'WP Debug Mode', 'rx-theme' ); ?></span>
<?php echo ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? self::status_badge( 'warning', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'good', __( 'Disabled', 'rx-theme' ) ); ?>
</li>
</ul>
<div class="rx-dashboard-actions">
<a href="#" class="button rx-clear-dashboard-cache" data-nonce="<?php echo esc_attr( wp_create_nonce( 'rx_clear_dashboard_cache' ) ); ?>">
<?php esc_html_e( 'Clear RX Cache', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'site-health.php?tab=debug' ) ); ?>">
<?php esc_html_e( 'Debug Info', 'rx-theme' ); ?>
</a>
</div>
</div>
<?php
}
/**
* Security Widget.
*/
public static function render_security_widget() {
$ssl = is_ssl();
$file_edit_disabled = defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT;
$wp_debug = defined( 'WP_DEBUG' ) && WP_DEBUG;
$admin_user_exists = username_exists( 'admin' );
$xmlrpc_file = ABSPATH . 'xmlrpc.php';
$xmlrpc_exists = file_exists( $xmlrpc_file );
$uploads = wp_upload_dir();
$uploads_index = trailingslashit( $uploads['basedir'] ) . 'index.php';
$uploads_index_exists = file_exists( $uploads_index );
?>
<div class="rx-dashboard-wrap">
<ul class="rx-dashboard-list">
<li>
<span><?php esc_html_e( 'HTTPS / SSL', 'rx-theme' ); ?></span>
<?php echo $ssl ? self::status_badge( 'good', __( 'Active', 'rx-theme' ) ) : self::status_badge( 'danger', __( 'Not Active', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Theme/Plugin File Editor', 'rx-theme' ); ?></span>
<?php echo $file_edit_disabled ? self::status_badge( 'good', __( 'Disabled', 'rx-theme' ) ) : self::status_badge( 'warning', __( 'Enabled', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'WP Debug on Live Site', 'rx-theme' ); ?></span>
<?php echo $wp_debug ? self::status_badge( 'warning', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'good', __( 'Disabled', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Default Admin Username', 'rx-theme' ); ?></span>
<?php echo $admin_user_exists ? self::status_badge( 'warning', __( 'Exists', 'rx-theme' ) ) : self::status_badge( 'good', __( 'Not Found', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'XML-RPC File', 'rx-theme' ); ?></span>
<?php echo $xmlrpc_exists ? self::status_badge( 'info', __( 'Present', 'rx-theme' ) ) : self::status_badge( 'good', __( 'Removed', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Uploads Index Protection', 'rx-theme' ); ?></span>
<?php echo $uploads_index_exists ? self::status_badge( 'good', __( 'Index Exists', 'rx-theme' ) ) : self::status_badge( 'info', __( 'Missing', 'rx-theme' ) ); ?>
</li>
</ul>
<p class="rx-muted rx-small">
<?php esc_html_e( 'Security status is a helpful checklist only. Use a dedicated security plugin or server firewall for deeper protection.', 'rx-theme' ); ?>
</p>
<div class="rx-dashboard-actions">
<a class="button" href="<?php echo esc_url( admin_url( 'users.php' ) ); ?>">
<?php esc_html_e( 'Manage Users', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'update-core.php' ) ); ?>">
<?php esc_html_e( 'Updates', 'rx-theme' ); ?>
</a>
</div>
</div>
<?php
}
/**
* Recent Content Widget.
*/
public static function render_recent_content_widget() {
$recent_posts = get_posts(
array(
'post_type' => array( 'post', 'page' ),
'post_status' => array( 'publish', 'draft', 'pending', 'future' ),
'posts_per_page' => 8,
'orderby' => 'modified',
'order' => 'DESC',
'no_found_rows' => true,
)
);
?>
<div class="rx-dashboard-wrap">
<?php if ( ! empty( $recent_posts ) ) : ?>
<ul class="rx-dashboard-list">
<?php foreach ( $recent_posts as $post ) : ?>
<li>
<span>
<a href="<?php echo esc_url( get_edit_post_link( $post->ID ) ); ?>">
<?php echo esc_html( get_the_title( $post->ID ) ? get_the_title( $post->ID ) : __( '(No title)', 'rx-theme' ) ); ?>
</a>
<br>
<span class="rx-muted rx-small">
<?php echo esc_html( ucfirst( $post->post_type ) ); ?> ·
<?php echo esc_html( ucfirst( $post->post_status ) ); ?> ·
<?php echo esc_html( human_time_diff( get_post_modified_time( 'U', true, $post ), current_time( 'timestamp', true ) ) . ' ago' ); ?>
</span>
</span>
<span>
<a class="button button-small" href="<?php echo esc_url( get_permalink( $post->ID ) ); ?>" target="_blank" rel="noopener">
<?php esc_html_e( 'View', 'rx-theme' ); ?>
</a>
</span>
</li>
<?php endforeach; ?>
</ul>
<?php else : ?>
<p><?php esc_html_e( 'No recent content found.', 'rx-theme' ); ?></p>
<?php endif; ?>
<div class="rx-dashboard-actions">
<a class="button button-primary" href="<?php echo esc_url( admin_url( 'post-new.php' ) ); ?>">
<?php esc_html_e( 'Add New Post', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'post-new.php?post_type=page' ) ); ?>">
<?php esc_html_e( 'Add New Page', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'edit.php' ) ); ?>">
<?php esc_html_e( 'All Posts', 'rx-theme' ); ?>
</a>
</div>
</div>
<?php
}
/**
* Quick Actions Widget.
*/
public static function render_quick_actions_widget() {
$nonce = wp_create_nonce( 'rx_dashboard_action' );
?>
<div class="rx-dashboard-wrap">
<p class="rx-muted">
<?php esc_html_e( 'Fast links for common RX Theme and WordPress tasks.', 'rx-theme' ); ?>
</p>
<div class="rx-dashboard-actions">
<a class="button button-primary" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>">
<?php esc_html_e( 'Open Customizer', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'widgets.php' ) ); ?>">
<?php esc_html_e( 'Widgets', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'nav-menus.php' ) ); ?>">
<?php esc_html_e( 'Menus', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'upload.php' ) ); ?>">
<?php esc_html_e( 'Media Library', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'plugins.php' ) ); ?>">
<?php esc_html_e( 'Plugins', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'themes.php' ) ); ?>">
<?php esc_html_e( 'Themes', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'options-general.php' ) ); ?>">
<?php esc_html_e( 'Settings', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( admin_url( 'tools.php' ) ); ?>">
<?php esc_html_e( 'Tools', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'rx_dashboard_action', 'flush_rewrite_rules', admin_url( 'index.php' ) ), 'rx_dashboard_action', '_rxnonce' ) ); ?>">
<?php esc_html_e( 'Flush Permalinks', 'rx-theme' ); ?>
</a>
<a class="button" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'rx_dashboard_action', 'clear_rx_transients', admin_url( 'index.php' ) ), 'rx_dashboard_action', '_rxnonce' ) ); ?>">
<?php esc_html_e( 'Clear RX Transients', 'rx-theme' ); ?>
</a>
</div>
<p class="rx-muted rx-small">
<?php esc_html_e( 'Use quick actions carefully on production websites.', 'rx-theme' ); ?>
</p>
</div>
<?php
}
/**
* System Info Widget.
*/
public static function render_system_info_widget() {
global $wpdb;
$mysql_version = $wpdb->db_version();
$server = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : __( 'Unknown', 'rx-theme' );
$max_upload = size_format( wp_max_upload_size() );
$timezone = wp_timezone_string();
$locale = get_locale();
$multisite = is_multisite();
$debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG;
?>
<div class="rx-dashboard-wrap">
<ul class="rx-dashboard-list">
<li>
<span><?php esc_html_e( 'Server Software', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $server ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'PHP Version', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( PHP_VERSION ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Database Version', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $mysql_version ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Max Upload Size', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $max_upload ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Timezone', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $timezone ? $timezone : 'UTC' ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Locale', 'rx-theme' ); ?></span>
<strong><?php echo esc_html( $locale ); ?></strong>
</li>
<li>
<span><?php esc_html_e( 'Multisite', 'rx-theme' ); ?></span>
<?php echo $multisite ? self::status_badge( 'info', __( 'Yes', 'rx-theme' ) ) : self::status_badge( 'good', __( 'No', 'rx-theme' ) ); ?>
</li>
<li>
<span><?php esc_html_e( 'Debug Log', 'rx-theme' ); ?></span>
<?php echo $debug_log ? self::status_badge( 'warning', __( 'Enabled', 'rx-theme' ) ) : self::status_badge( 'good', __( 'Disabled', 'rx-theme' ) ); ?>
</li>
</ul>
</div>
<?php
}
/**
* Developer Notes Widget.
*/
public static function render_developer_notes_widget() {
$template_dir = get_template_directory();
$stylesheet_dir = get_stylesheet_directory();
$recommended_files = array(
'functions.php',
'inc/enqueue.php',
'inc/theme-setup.php',
'inc/template-functions.php',
'inc/admin/dashboard-widgets.php',
'inc/options/color-options.php',
'inc/options/typography-options.php',
'inc/security/security.php',
'inc/performance/performance.php',
'inc/seo/seo.php',
);
?>
<div class="rx-dashboard-wrap">
<p>
<?php esc_html_e( 'Recommended RX Theme modular structure check:', 'rx-theme' ); ?>
</p>
<ul class="rx-dashboard-list">
<?php foreach ( $recommended_files as $file ) : ?>
<?php
$parent_exists = file_exists( trailingslashit( $template_dir ) . $file );
$child_exists = file_exists( trailingslashit( $stylesheet_dir ) . $file );
$exists = $parent_exists || $child_exists;
?>
<li>
<span class="rx-code"><?php echo esc_html( $file ); ?></span>
<?php echo $exists ? self::status_badge( 'good', __( 'Found', 'rx-theme' ) ) : self::status_badge( 'info', __( 'Optional', 'rx-theme' ) ); ?>
</li>
<?php endforeach; ?>
</ul>
<p class="rx-muted rx-small">
<?php esc_html_e( 'This widget helps you keep RX Theme clean, modular, and developer-friendly.', 'rx-theme' ); ?>
</p>
</div>
<?php
}
/**
* Handle quick dashboard actions.
*/
public static function handle_quick_actions() {
if ( ! is_admin() || ! current_user_can( self::$capability ) ) {
return;
}
if ( empty( $_GET['rx_dashboard_action'] ) ) {
return;
}
if ( empty( $_GET['_rxnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_rxnonce'] ) ), 'rx_dashboard_action' ) ) {
wp_die( esc_html__( 'Security check failed.', 'rx-theme' ) );
}
$action = sanitize_key( wp_unslash( $_GET['rx_dashboard_action'] ) );
switch ( $action ) {
case 'flush_rewrite_rules':
flush_rewrite_rules();
self::redirect_with_message( 'rx_permalinks_flushed' );
break;
case 'clear_rx_transients':
self::clear_rx_transients();
self::redirect_with_message( 'rx_transients_cleared' );
break;
}
}
/**
* AJAX clear dashboard cache.
*/
public static function ajax_clear_dashboard_cache() {
if ( ! current_user_can( self::$capability ) ) {
wp_send_json_error(
array(
'message' => __( 'Permission denied.', 'rx-theme' ),
)
);
}
check_ajax_referer( 'rx_clear_dashboard_cache', 'nonce' );
self::clear_rx_transients();
wp_send_json_success(
array(
'message' => __( 'RX dashboard cache cleared.', 'rx-theme' ),
)
);
}
/**
* Add custom items to WordPress "At a Glance".
*/
public static function add_glance_items( $items ) {
if ( ! current_user_can( self::$capability ) ) {
return $items;
}
$theme = wp_get_theme();
$items[] = sprintf(
'<a href="%1$s">%2$s</a>',
esc_url( admin_url( 'themes.php' ) ),
esc_html( sprintf( __( 'RX Theme: %s', 'rx-theme' ), $theme->get( 'Version' ) ? $theme->get( 'Version' ) : '1.0.0' ) )
);
return $items;
}
/**
* Get plugin count.
*/
private static function get_plugin_count() {
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$plugins = get_plugins();
$active_plugins = (array) get_option( 'active_plugins', array() );
return array(
'total' => count( $plugins ),
'active' => count( $active_plugins ),
);
}
/**
* Clear RX transients.
*/
private static function clear_rx_transients() {
global $wpdb;
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
$wpdb->esc_like( '_transient_rx_' ) . '%',
$wpdb->esc_like( '_transient_timeout_rx_' ) . '%'
)
);
wp_cache_flush();
}
/**
* Redirect after action.
*/
private static function redirect_with_message( $message ) {
wp_safe_redirect(
add_query_arg(
array(
'rx_dashboard_message' => sanitize_key( $message ),
),
admin_url( 'index.php' )
)
);
exit;
}
/**
* Return theme version.
*/
private static function theme_version() {
$theme = wp_get_theme();
return $theme->get( 'Version' ) ? $theme->get( 'Version' ) : '1.0.0';
}
/**
* Status badge helper.
*/
private static function status_badge( $type, $text ) {
$type = sanitize_html_class( $type );
return sprintf(
'<span class="rx-status rx-status-%1$s">%2$s</span>',
esc_attr( $type ),
esc_html( $text )
);
}
}
RX_Theme_Dashboard_Widgets::init();
endif;
Now include it in your functions.php:
/**
* RX Theme Admin Dashboard Widgets.
*/
if ( is_admin() ) {
require_once get_template_directory() . '/inc/admin/dashboard-widgets.php';
}
Best folder structure:
rx-theme/
├── functions.php
└── inc/
└── admin/
└── dashboard-widgets.php
This file is safe for a theme because it only loads in the admin dashboard and checks manage_options permission before showing advanced dashboard information.