Is it possible to add Custom Dashboard Widgets to Custom Admin Menu Page?

TL;DR: Yes, it’s possible to add a Custom Dashboard Widget to a Custom Admin Menu Page.

Option-1: Without the dashboard like UI:

If all you want is just displaying the custom Widget data (without the UI), then you can simply call the function that was used to display the custom dashboard widget content.

For your CODE, display_chess_news_admin_page function can call display_chess_blogger_widget to show the same content (without the dashboard like meta box UI). Like this:

// Function to display the custom admin page
function display_chess_news_admin_page() {
    echo '<h1>Chess News</h1>';
    echo '<p>Welcome to the Chess News admin page.</p>';
    display_chess_blogger_widget();
}

Option-2: With the dashboard like UI:

However, I’m assuming you want similar Widget UI that the dashboard has, but on this custom Admin Menu Page.

To achieve that, you may use the meta box API or duplicate part of the code from the WordPress core dashboard implementation.

The meta box API is explained in the documentation link I’ve provided above. So here I’m showing the dashboard duplication way:

  1. Include this core file: wp-admin/includes/dashboard.php.

  2. Use dashboard HTML wrapper code:

<div class="wrap">
    <div id="dashboard-widgets-wrap">
        <!-- dashboard widget code here -->
        <div class="clear"></div>
    </div>
</div>
  1. Call wp_dashboard() function.

  2. Include dashboard JavaScript and CSS:

wp_enqueue_script( 'dashboard' );
wp_admin_css( 'dashboard' );

Below is a sample CODE of a complete plugin that demonstrates how it could be done:

<?php
/*
Plugin Name: Admin Page Custom Dashboard
*/

// Function to create custom admin page
function create_chess_news_admin_page() {
    add_menu_page(
        'Chess News',                       // Page title
        'Chess News',                       // Menu title
        'manage_options',                   // Capability
        'chess_news',                       // Menu slug
        'display_chess_news_admin_page',    // Function to display the page
        'dashicons-media-text',             // Icon URL
        6                                   // Position in menu
    );
}
add_action( 'admin_menu', 'create_chess_news_admin_page' );

// Function to display the custom admin page
function display_chess_news_admin_page() {
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( 'You do not have permission to view this page.' );
    }
    ?>
    <div class="content-body">
        <h1>Chess News</h1>
        <p>Welcome to the Chess News admin page.</p>
        <?php
            // Load Dashboard
            display_chess_dashboard_ui(); 
        ?>
    </div><!-- content-body -->
    <?php
}

// This function prints the custom dashboard UI for this admin menu page
function display_chess_dashboard_ui() {
    // Include the admin dashboard code from WP core
    require_once ABSPATH . 'wp-admin/includes/dashboard.php';

    create_chess_blogger_dashboard_widget();
    ?>
    <div class="wrap">
        <div id="dashboard-widgets-wrap">
            <?php
                // Display this custom dashboard just like the main admin dashboard,
                // but with custom Widgets for this custom admin page only
                wp_dashboard();
            ?>
            <div class="clear"></div>
        </div><!-- dashboard-widgets-wrap -->
    </div><!-- wrap -->
    <?php
}

// Function to create custom dashboard widget
function create_chess_blogger_dashboard_widget() {
    // Chess blogger RSS widget
    wp_add_dashboard_widget(
        'chess_blogger_widget',         // Widget slug
        'Chess Blogger',                // Widget title
        'display_chess_blogger_widget'  // Function to display the widget
    );

    // Another sample widget
    wp_add_dashboard_widget(
        'chess_info_widget',            // Widget slug
        'Chess Info',                   // Widget title
        'display_chess_info_widget'     // Function to display the widget
    );
}

// Function to display the custom dashboard widget
function display_chess_blogger_widget() {
    // Get RSS feed
    include_once( ABSPATH . WPINC . '/feed.php' );
    $rss = fetch_feed( 'https://chessblogger.org/feed/' );

    // Check for errors
    if ( is_wp_error( $rss ) ) {
        echo '<p>An error occurred while retrieving the RSS feed.</p>';
        return;
    }

    // Get the 5 most recent items from the RSS feed
    $maxitems = $rss->get_item_quantity( 5 );
    $rss_items = $rss->get_items( 0, $maxitems );

    echo '<ul>';
    foreach ( $rss_items as $item ) {
        echo '<li><a href="' . $item->get_permalink() . '">' . $item->get_title() . '</a></li>';
    }
    echo '</ul>';
}

function display_chess_info_widget() {
    echo '<p>Here is your chess info.</p>';
}

// These scripts are needed for custom dashboard
function chess_dashboard_scripts() {
    wp_enqueue_script( 'dashboard' );
    wp_admin_css( 'dashboard' );
}
add_action( 'admin_enqueue_scripts', 'chess_dashboard_scripts', 9 );

/* 
 * Note: CODE below this line is only for adding the custom widgets to the dashboard.
 * Uncomment if you need it.
 */
// add_action( 'wp_dashboard_setup', 'create_chess_blogger_dashboard_widget' );