Help Tabs with: add_help_tab() callback – How does the argument work?

I just tried to add a simple help tab, from within a class (example to test below). I wanted to use a helper/callback fn to prepare the content for different help tabs. According to core, the function takes some args:

WP 3.3 /wp-admin/includes/screen.php LINE 722

Read More
     // If it exists, fire tab callback.
     if ( ! empty( $tab['callback'] ) )
        call_user_func_array( $tab['callback'], array( $this, $tab ) );

For some reason I get the complete WP_Screen object in the callback, instead of just the tab. See PasteBin here.

Here’s the example. For your convenience, as a plugin, so testing is easier (on post screens).

<?php
/**
 * Plugin Name: Help Tab Test Case
 * Plugin URI:  http://unserkaiser.com
 * Description: Add Help Tab test case
 */
class example_help
{
    public $tabs = array(
         'EXAMPLE' => array(
             'title'   => 'TEST ME!'
            ,'content' => 'FOO'
         )
    );

   static public function init()
    {
        $class = __CLASS__ ;
        new $class;
    }

    public function __construct()
    {
        add_action( "load-{$GLOBALS['pagenow']}", array( $this, 'add_tabs' ), 20 );
    }

    public function add_tabs()
    {
        foreach ( $this->tabs as $id => $data )
        {
            get_current_screen()->add_help_tab( array(
                 'id'       => $id
                ,'title'    => __( $data['title'], 'some_textdomain' )
                ,'content'  => $data['content']
                ,'callback' => array( $this, 'prepare' )
            ) );
        }
    }

    /* HELPER */
    public function prepare( $tab )
    {
error_reporting( E_ALL );
// FAILS: return blank
// _dump( $tab['tabs'] );
// No error output on screen
var_dump( $tab );

// I can dump it using my own function, 
// that adds the data to a global and then calls & prints it on shutdown
// See pastebin for content
// _dump( $tab );
        return printf( 
             '<p>%s</p>'
            ,__( 'test', 'dmb_textdomain' )
        );
    }
}
add_action( 'load-post.php', array( 'example_help', 'init' ) );
add_action( 'load-post-new.php', array( 'example_help', 'init' ) );

Edit:

If I just output print $tab in the callback, I get Array as output string above the actual content (WP_Screen is an object). I tried dumping all parts of the array without any result (white screen, no error).

Related posts

Leave a Reply

2 comments

  1. Ok. The answer is NOT simple, but after some try and error, reading core, etc. I found out what the problem is:

    The callback (which should be used instead of the content) accepts two arguments: $current_screen and $tab.

    Here’s what $tab looks like, when dumped for a single tab.

    Array
    (
        [title] => TEST ME
        [id] => EXAMPLE_A
        [content] => 
        [callback] => Array
            (
                [0] => dmb_help Object
                    (
                        [tabs] => Array
                            (
                                [EXAMPLE_A] => Array
                                    (
                                        [title] => TEST ME
                                        [content] => FOO
                                    )
    
                                [EXAMPLE_B] => Array
                                    (
                                        [title] => TEST ME ALSO
                                        [content] => BAR
                                    )
    
                            )
    
                    )
    
                [1] => prepare
            )
    
    )
    

    IMPORTANT INFO: You’re not!! (never ever anyhow) allowed to use spaces inside an id-string. Then you can get the actual content from the object:

    public function prepare( $screen, $tab )
    {
        printf( 
             '<p>%s</p>'
            ,__( 
                 $tab['callback'][0]->tabs[ $tab['id'] ]['content']
                ,'some_textdomain' 
             )
        );
    }
    

    You should drop content in the input array completely (until you don’t want to add some repeating content when looping through multiple help tabs).

    Final working example:

    Here’s the working text case as plugin.

    <?php
    /**
     * Plugin Name: Help Tab Test Case
     * Plugin URI:  http://unserkaiser.com
     * Description: Add Help Tab test case
     */
    class example_help
    {
        public $tabs = array(
            // The assoc key represents the ID
            // It is NOT allowed to contain spaces
             'EXAMPLE' => array(
                 'title'   => 'TEST ME!'
                ,'content' => 'FOO'
             )
        );
    
        static public function init()
        {
            $class = __CLASS__ ;
            new $class;
        }
    
        public function __construct()
        {
            add_action( "load-{$GLOBALS['pagenow']}", array( $this, 'add_tabs' ), 20 );
        }
    
        public function add_tabs()
        {
            foreach ( $this->tabs as $id => $data )
            {
                get_current_screen()->add_help_tab( array(
                     'id'       => $id
                    ,'title'    => __( $data['title'], 'some_textdomain' )
                    // Use the content only if you want to add something
                    // static on every help tab. Example: Another title inside the tab
                    ,'content'  => '<p>Some stuff that stays above every help text</p>'
                    ,'callback' => array( $this, 'prepare' )
                ) );
            }
        }
    
        public function prepare( $screen, $tab )
            {
                printf( 
                 '<p>%s</p>'
                ,__( 
                         $tab['callback'][0]->tabs[ $tab['id'] ]['content']
                    ,'dmb_textdomain' 
                 )
            );
        }
    }
    // Always add help tabs during "load-{$GLOBALS['pagenow'}".
    // There're some edge cases, as for example on reading options screen, your
    // Help Tabs get loaded before the built in tabs. This seems to be a core error.
    add_action( 'load-post.php', array( 'example_help', 'init' ) );
    add_action( 'load-post-new.php', array( 'example_help', 'init' ) );
    
  2. If you don’t know how many or what kind of arguments reach your callback, try this two usefull php functions:

    func_num_args()
    

    and

    func_get_args()
    

    The first one shows you how many arguments are send. The second gives you an array with the arguments.

    public function prepare(){
    
       echo 'Number of arguments: ' . $func_num_args();
       echo 'Arguments:';
       var_dump( func_get_args() );
    
    }