Use wp_localize_script for non existing script

Task: What I’m trying to do

I’m fetching data via the WP Http API from a remote server. The data I’m getting back is JSON encoded. In one of my methods, I’m converting them back and then push it into a class variable, so I can use it later in some scripts.

Example: How I’m trying to do it

// Simplified... please note, that all names/vars/etc. in my class got unique names.
// ...the same goes for the script handler.
class http_api_example
{
    public $remote_data;
    public $response;

    public function __construct()
    {
        $this->request();
    }

    public function request()
    {
        $request = wp_remote_request( 'http://example.com/HereYouGetSomeJSON' );
        $this->response = json_decode( wp_remote_retrieve_body( $request ) );
    }

    public function deliver_to_javascript()
    {
        wp_enqueue_script( 'json_handler', null, array(), null, true );

        // ...then I'm trying to localize it
        wp_localize_script( 'json_handler, 'json_object', array(
             'ajaxurl'    => admin_url( 'admin-ajax.php' )
            ,'ajax_nonce' => wp_create_nonce( 'json_handler_nonce' )
            ,'action'     => 'json-handler-action'
            ,'data'       => $this->response
         )

    }
}

Problem: What’s not working

For some reason, I can’t access the json_object from the console (it works for other objects in other classes just fine).

Read More

Debug so far

Is it registered and queued?

I tried to take a look if the script is registered:

// 'registered': TRUE
var_dump( wp_script_is( 'json_object' ) );

// 'queue': TRUE
var_dump( wp_script_is( 'json_object', 'queue' ) );

to be sure, I’ve also taken a look into the global $wp_scripts and can confirm, that it’s there.

Is it localized?

// Data shows up, JSON encoded
var_dump( $GLOBALS['wp_scripts']->registered['json_object']->extra;

Where in core does it stop?

I went into core and backtraced it the following way:

  1. wp_localize_script() ✓
  2. » $wp_scripts->localize() ✓
  3. »» WP_Dependencies: add_data() ✓
  4. »»» WP_Dependencies: add_data() FIN!

The FIN! notes a call to itself. As you can see from the Link to the WP repo on GitHub, inside ->add_data(), there’s another call to ->add_data() (to itself). I dumped the result and got TRUE back.

I’m currently out of “what can I try else?”-options. Maybe someone got an idea, how this is supposed to work or maybe just where I could try to look further.

Thanks.

Related posts

Leave a Reply

2 comments

  1. How does core do it?

    After thinking again about it, I thought there might be a case where WP does the same thing internally. And right: It does it.

    Example ~/wp-admin/load-scripts.php

    $wp_scripts = new WP_Scripts();
    wp_default_scripts($wp_scripts);
    
    // inside wp_default_scripts( &$scripts )
    $scripts->add( $handle, $src, $dependencies, $version, $args ); // from WP_Dependencies
    $scripts->localize( $handle, $object_name, $data ); // from WP_Scripts
    

    This means, that there is a way, but only with using the internals directly.

    So, to add & localize a non-existing file, you just do add false instead of $src:

    $wp_scripts->add(
        'your_handle',
        false,
        array(),
        null,
        true
    );
    $wp_scripts->localize(
        'your_handle',
        "your_handle_object",
        array(
            'ajaxurl'    => admin_url( 'admin-ajax.php' ),
            'ajax_nonce' => wp_create_nonce( "your_handle-nonce" ),
            'action'     => "your_handle-action",
            'data'       => array(), // Whatever data you need to transport
        )
    );
    
  2. Disclaimer: This doesn’t answer my question completely.

    I just found out, that the problem is, that I was using no name.

    Half of a solution…

    If you’re adding some random string, then WP_Scripts/WP_Dependencies/_WP_Dependencies will give you the desired javascript object.

    Drawback: If the file doesn’t exist, it will still be registered and end in a failed GET, which may be responsible for slowing your site down (depending on the timeout).

    Temporary work around: You can add an empty(!) file, that will load pretty fast and … do nothing.

    Note

    This doesn’t answer my question fully, as I’d be pleased to know where to look furhter. WP 3.5 development just started and it is enough time to write a patch/ticket for this… at least if I know where the actual problem is. I just can’t see a reason, why this only works with a file, when the actual javascript object will be pushed into the global namespace.