Is there a way to know the name of all variables passed by wp_localize_script?

Dynamic variable names are unpleasant to work with. A slightly better solution would be to use a single array / object which references each ‘instance’ using an auto-incremented integer.

This isn’t a far cry from what you have already, but it keeps all you parameters inside on variable, and accessing a particular property of an object just feels nicer than dynamically creating the variable name.

The problem is, that wp_localize_script() obliterates previous calls when the object name is the same. So to ensure that you can ‘collate’ your parameters, you can make use of static class to store the parameters and enqueue the script as late on as possible (for the front-end wp_footer will do).

Here’s a brief example:

class My_js_loader{

    private static $scripts;

    static function enqueue( $handle, $args ){
         if ( ! isset( self::$scripts[$handle] ) ) {
              self::$scripts[$handle] = array();
         }

         self::$scripts[$handle][] = $args;

         add_action( 'wp_footer', array( __CLASS__, 'enqueue_scripts' ) );

         return count( self::$scripts );
    }

    static function enqueue_scripts(){
         if ( self::$scripts ) {
              foreach( self::$scripts as $handle => $args ){
                   wp_enqueue_script( $handle );
                   wp_localize_script( $handle, $handle, $args );
              }
         }
    }

}

An example usage:

 $instance1_id = My_js_loader::enqueue( 'mywidget', array( 
     'param1' => 'foo',
     'param2' => 'bar',
 ) );
 //$instance1_id = 1;
 //generates HTML <div class="mywidget" data-mywidget-instance="1"></div>


 $instance2_id = My_js_loader::enqueue( 'mywidget', array( 
     'param1' => 'hello',
     'param2' => 'world',
 ) );
 //$instance2_id = 2;
 //generates HTML <div class="mywidget" data-mywidget-instance="2"></div>

Then in the javascript file

 $('.mywidget').each(function(){
      var inst = $(this).data('mywidget-instance');
      var args = mywidget[inst];
 });

Disadvantages

  • I’m assuming that your JavaScript handle works as a variable name. If that is not the case you can always allow a variable name to be passed to My_js_loader::enqueue() too.
  • The late loading means that it can’t be dequeued easily. You could expose a dequeue method (to prevent a particular, or all current instances, from loaded). However it most cases, the corresponding mark-up has already been printed to the page, so you probably don’t want it dequeued.
  • Use of static class makes testing… awkward…

Advantages

  • Avoids the situation where if your script has already been printed to the page, further calls to wp_localize_script() are ignored.
  • All parameters are contained with a nice, known and fixed variable name
  • JavaScript file always loads in the footer