3

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

     // 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).

3

2 Answers 2

4

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' ) );
1

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() );

}
1
  • The really painful thing was to find out, that I need $tab['callback'][0]->tabs[ $tab['id'] ]['content'], to get the actual content.
    – kaiser
    Commented May 30, 2012 at 9:31

Your Answer

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

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