6

TL;DR : In simple terms, I just want to add a Dashboard Widget created by our plugin using wp_add_dashboard_widget function, to a custom Admin Menu Page created by the same plugin using add_menu_page function.

Is this possible?


Here is the code I've used to create the Admin Menu Page:

// 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() {
    echo '<h1>Chess News</h1>';
    echo '<p>Welcome to the Chess News admin page.</p>';
}

This is how I have created the Custom Dashboard Widget:

// Function to create custom dashboard widget
function create_chess_blogger_dashboard_widget() {
    wp_add_dashboard_widget(
        'chess_blogger_widget', // Widget slug
        'Chess Blogger', // Widget title
        'display_chess_blogger_widget' // Function to display the widget
    );
}
add_action( 'wp_dashboard_setup', 'create_chess_blogger_dashboard_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>';
}

Now I want to display the above Dashboard Widget on the Admin Menu Page I created, instead of the default WordPress Admin Dashboard.

7
  • please edit the question to include the code for your custom admin page so we can see how you've created a dashboard type area for us to add widgets too ( or to demonstrate where such an area would be added if you do not know how )
    – Tom J Nowell
    Jan 27 at 10:13
  • @TomJNowell I updated the question.
    – Ranuka
    Jan 27 at 14:59
  • ok so you don't actually have a dashboard, you have a custom admin page that displays an RSS feed, so this isn't just about adding it to the custom dashboard, it's about building it all from scratch!
    – Tom J Nowell
    Jan 27 at 15:09
  • If it's a dashboard widget, then it goes on the dashboard... ...if you're putting it on a custom admin page then it's not really a 'dashboard widget'. You can replicate the HTML markup so that it looks like a dashboard widget but really you're just building your own function that looks the same as a dashboard widget in your custom admin screen. Question: What's not working about your code? I've built a dashboard widget that displays an RSS feed, so I may be able to help. Jan 27 at 15:17
  • 1
    dashboard widgets are an added layer on top of the metabox API, you can have these outside of the dashboard, but it requires additional setup, and use of the metabox API to insert your dashboard boxes/widgets. You shouldn't have to implement any drag and drop code
    – Tom J Nowell
    Jan 27 at 21:39

1 Answer 1

4
+50

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' );
3
  • 1
    Didn't think of including the dashboard code elsewhere with wp_dashboard() call. Interesting!
    – Futuritous
    Feb 1 at 1:17
  • Thanks, This is exactly what I want. I think you don't need include_once( ABSPATH . WPINC . '/feed.php' ); because fetch_feed works without it. And inside chess_dashboard_scripts, don't we need to exclude the main dashboard page since those js/css is already there? And I didn't understand how wp_dashboard(); work in this page.
    – Ranuka
    Feb 1 at 13:38
  • 1
    1. For feed code, I just copied your code, just to demonstrate how it works. Didn't give much thought on it. 2. Main dashboard's js/css are only loaded on the main dashboard, not on your custom pages. 3. wp_dashboard() function executes the related hooks that are needed to output the widgets created by wp_add_dashboard_widget calls.
    – Fayaz
    Feb 1 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.