3

I've been busy thinking about a problem, and so far I didn't find a solution to it.

The abstract scenario

On admin page A, I would like to print the value of a (global) variable—in the context of admin page B, though.

The concrete scenario

On a custom user-options page, I would like to list all metaboxes registered for each post type.

Both plugins and the theme can add/remove metaboxes with respect to the current page context ($pagenow). Thus, the $wp_meta_boxes global is set up in that context.


So far, I've read into virtually any hook, read a lot on AJAX (the right and the wrong ways), and tried out numerous different approaches I came up with. Unfortunatly, without luck.

The question

Is it possible to retrieve the value of $wp_meta_boxes on admin page post-new.php?post_type=my_super_duper_post_type, for instance, from another admin page?

If so, how would I go about that?

Can this be done via AJAX?
Or can I trick the plugins/theme into thinking that the current page is post-new.php?post_type=my_super_duper_post_type, for instance, while we're actually on my options page?

3
+50

Ok, this could be achieved this way, probably.

add_action('add_meta_boxes_my_super_duper_post_type', 'get_metabox_global_ajax', 9999 );
function get_metabox_global_ajax(){
    if( isset($_GET['mgv']) && $_GET['mgv'] == '1' ){
        global $wp_meta_boxes;
        @error_reporting( 0 );
        header( 'Content-type: application/json' );
        die( json_encode( $wp_meta_boxes ));
    }
}

Now, you send a request from your plugin page to post-new.php?post_type=my_super_duper_post_type&mgv=1 through ajax, and use the returned json response of wp_meta_boxeses variables.

  • Wow, thanks, that was quick. I will try this out and report back later (i.e., tomorrow). // Edit: Just for information, I never came across the add_meta_boxes_{$post_type} hook, so far. In case your complete answer shouldn't work, this is helpful nonetheless. – tfrommen Dec 11 '13 at 16:16
1

Thanks to @Shazzad and @G.M., I found the right track.

Here is a short outline of what I did:

The JavaScript/AJAX action

jQuery(function($) {
    for (var i = 0; i < localizedData.postTypes.length; ++i) {
        $.ajax({
            type: 'post',
            url: 'post-new.php?post_type='+localizedData.postTypes[i],
            data: {
                action: 'my-plugin-action',
                _ajax_nonce: localizedData.nonce
            },
            success: function(data) {
                if (data) {
                    doSomethingWithTheBoxes(data.metaBoxes);
                }
            }
        });
    }
});

Enqueue the JavaScript file for my custom user options page

$post_types = array(
    'post',
    'page',
    'my_custom_post_type',
);

if ('users' === basename($pagenow, '.php'))
    add_action('admin_print_scripts-users_page_my-plugin-page', 'MyPlugin_enqueue_scripts');

function MyPlugin_enqueue_scripts() {
    $data = array(
        'nonce' => wp_create_nonce('my_plugin_nonce'),
        'postTypes' => $post_types,
    );
    $handle = 'my-plugin-js';
    wp_enqueue_script(
        $handle,
        plugin_dir_url(__FILE__).'my-plugin.js',
        array('jquery'),
        filemtime(plugin_dir_path(__FILE__).'my-plugin.js'),
        true
    );
    wp_localize_script($handle, 'localizedData', $data);
} // function MyPlugin_enqueue_scripts

Set up the right hook to handle the AJAX request

global $pagenow;

if ('post-new' === basename($pagenow, '.php'))
    add_action('do_meta_boxes', 'MyPlugin_get_meta_boxes', PHP_INT_MAX);

function MyPlugin_get_meta_boxes($post_type) {
    if (
        'my-plugin-action' == filter_input(INPUT_POST, 'action')
        && in_array($post_type, $post_types)
    ) {
        check_ajax_referer('my_plugin_nonce');

        wp_send_json(array(
            'metaBoxes' => $GLOBALS['wp_meta_boxes']
        ));
    }
} // function MyPlugin_get_meta_boxes

Now I am able to get all actually registered meta boxes for whatever post type I'd like—while being on some other admin page.

  • 1
    add_meta_boxes_'.$post_type run before do_meta_boxes. For me I'd used do_meta_boxes instead of using that high priority, adding action only once and moved the check for post type inside MyPlugin_get_meta_boxes, in fact do_meta_boxes pass post type as 1st argument. Then I'd used get_current_screen instead of rely on global $pagenow. And 2 tips: look at wp_send_json and use filter_input instead of direct access to $_POST and $_GET. – gmazzap Dec 18 '13 at 8:06
  • @G.M. Thanks a lot for these suggestions. In fact, I never heard of wp_send_json before. And using do_meta_boxes with the post type as argument instead of using add_meta_boxes_{$post_type} makes much more sense, too. I just overlooked that I could specify the post type (meaning the page) for this hook. Thanks again. – tfrommen Dec 18 '13 at 10:08
  • @tf Hi, I've a similar question about this stuff, do you know other way to access this without AJAX? here is my question wordpress.stackexchange.com/questions/154684/… – nonsensecreativity Jul 15 '14 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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