Custom wp_welcome_panel for every role or custom dashboard

I would love to customized and dumb down my dashboard with custom icons, shortcuts, guides, etc. I can do this already using widgets, but I would like to dare and do something better.

wp_welcome_panel on this regard, is awesome: I can customized it, I can make it show whatever I want but… only administrators can see this. So I was wondering:

Read More

1) Can I customize wp_welcome_panel so that every role can actually see it?

2) Can I add some code before the widgets in order to create a custom dashboard header similar to the one in wp_welcome_panel)? I already tried with

function mycustomcontent() {
    echo '<h1>Hello world</h1>';
}
add_action('load-index.php', 'mycustomcontent');

But… the HTML output is placed before anything (right after the body tag), even pushing down the sidebar.

Thanks in advance

Related posts

2 comments

  1. 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="<?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>
    
  2. There are two ways to do that.

    You can (a) Edit capability from edit_theme_options to read in wp source code.
    or (c) Change (override) capabilty on a fly for wp-admin/index.php for any usertype…

     add_filter('user_has_cap', 'se_119694_user_has_cap');
     function se_119694_user_has_cap($capabilities){
     global $pagenow;
          if ($pagenow == 'index.php')
               $capabilities['edit_theme_options'] = 1;
          return $capabilities;
     }
    

    My recommendation – do not do a and/or b.

    1. You changing core. Its bad.
    2. You giving permitions (even on
      homepage of wp-admin) that person don’t really need. Its a security
      HOLE.

    In this case you can deploy your panel just nead admin_footer action and using jQuery move it to the top

    add_action('admin_footer-index.php', 'se_119694_admin_footer');
    
    function se_119694_admin_footer(){
        echo '<div style="display:none;" class="welcome-panel" id="my_wellcome_panel">Hi!</div>';
        echo '
            <script>
                jQuery(window).ready(function(){
                    jQuery( "#my_wellcome_panel" ).insertAfter( jQuery( ".wrap h2" ) ).css("display", "block");
                });
            </script>
            ';
    
    }
    

Comments are closed.