Custom wp_welcome_panel for every role or custom dashboard

Where is the “Welcome Panel”?

The WordPress dashboard (which houses the “Welcome Panel”) basically is the

~/wp-admin/index.php

When does it show?

As you can see when looking at the source, there’s the following check:

if ( has_action( 'welcome_panel' ) && current_user_can( 'edit_theme_options' ) )

How to bypass the needed capability? Make it available for everyone!

This means that the minimum role/capability (role names get assigned as capabilities as well), is edit_theme_options. Now you can, as @OlegButuzov showed in his answer, either hook a callback to the user_has_cap filter, or the filter inside get_user_meta() – acutally a filter inside get_metadata() – named

apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );

Now a callback would look like the following. Make sure it’s hook as close to the welcome panel action as possible. 'all_admin_notices' would be a nice fit.

Make sure that you only trigger this filter callback on the dashboard and only once. Else you’d give a user unwanted capabilities, resulting in users having access to your actual theme settings. I used the WCM Current Admin Info plugin to retrieve that data.

// Hooking as late as possible
add_action( 'all_admin_notices', 'wpse119694AddCapCheckOverride' );
function wpse119694AddCapCheckOverride()
{
    // Do some check against get_current_screen()
    if ( 'dashboard' !== get_current_screen()->id )
        add_filter( 'get_user_metadata', 'wpse119694AddEditThemeOptionsCap', 20, 4 );
}

// The callback used to override the cap check
function wpse119694AddEditThemeOptionsCap( $return, $objectId, $metaKey, $single )
{
    // Instantly remove to avoid conflicts later on
    remove_filter( current_filter(), __FUNCTION__ );

    // Only for the current user
    if ( wp_get_current_user()->user_id !== $objectId )
        return $return;

    // Only for the 'edit_theme_options' cap
    if ( 'edit_theme_options' === $metaKey )
        return TRUE;

    return $return;
}

Additional: Show the welcome panel always

Users can dismiss the welcome panel. Sometimes we don’t want that as we assume that they haven’t read our important info/notes or for whatever reason. Note: You’ll need to internals yourself.

add_action( 'all_admin_notices', 'wpse119694AddCapCheckOverride' );
function wpse119694AddCapCheckOverride()
{
    // Do some check against get_current_screen()
    if ( 'dashboard' !== get_current_screen()->id )
        add_filter( 'get_user_metadata', 'wpse119694ShowWelcomePanel', 20, 4 );
}

function wpse119694ShowWelcomePanel( $return, $objectId, $metaKey, $single )
{
    // Instantly remove to avoid conflicts later on
    remove_filter( current_filter(), __FUNCTION__ );

    // Only for the current user
    if ( wp_get_current_user()->user_id !== $objectId )
        return $return;

    // ALWAYS show the welcome panel
    if ( 'show_welcome_panel' === $metaKey )
    {
        // Implement additional checks in here
        return TRUE;
    }

    return $return;
}

Custom content for the “Welcome Panel”

Now the first thing we need to do is getting rid of the original content. Then we can add our custom content based on a users ID/Name/Role/etc. Therefore we utilize wp_get_current_user(), which returns an instance of WP_User filled with all data we need.

// Hook as close to the welcome panel as possible
add_action( 'welcome_panel', 'wpse119684WelcomePanelContents' );
function wpse119684WelcomePanelContents()
{
    remove_all_actions( current_filter() );

    $userData = wp_get_current_user();

    $html = <<<EOF
<!-- custom HTML -->
EOF;

    // Here you start overriding the previous $html based on user capabilities.
    if ( 'some-check-against' === $userData )
        $html = <<<EOF
<!-- custom HTML for a specific Role/User/etc.
EOF;

    return $html;
}

Now you should be able to customize every bit of your “Welcome Panel” for every User/Role/Capability.

Reference MarkUp

A good reference to start coding your own “Welcome Panel” content for your user is cores default wp_welcome_panel() function.

<div class="welcome-panel-content">

    <h3><?php _e( 'Headline', 'your_textdomain' ); ?></h3>

    <p class="about-description"><?php _e( 'Intro', your_textdomain' ); ?></p>

    <div class="welcome-panel-column-container">

        <div class="welcome-panel-column">
             <h4><?php _e( 'Sub Headline', your_textdomain' ); ?></h4>
             <a class="button button-primary button-hero hide-if-customize" href="https://wordpress.stackexchange.com/questions/119694/<?php echo get_edit_user_link(); ?>">
                 <?php _e( 'Want to complete your profile? :)', 'your_textdomain' ); ?>
             </a>
        </div>

        <div class="welcome-panel-column">
            <?php /* Some more content in another column */ ?>
        </div>

        <div class="welcome-panel-column welcome-panel-last">
            <?php /* The last column */ ?>
        </div>

    </div>

</div>

Leave a Comment