31

Can we somehow use wp_localize_script() to create global js variables without a specific script handle which can be accessed from all the js files, even if the js scripts are not enqueued properly by using wp_enqueue_script ?

This is the code I am using which creates varibale for 'ajaxscript' handle, so I cant access the object 'ajaxobject' in a js file which is being included in the header.php directly by <script src="xxx" .... />

wp_register_script( 'ajaxscript', get_bloginfo( 'template_url' ) . '/js/ajaxscript.js', array(), $version );
wp_enqueue_script( 'ajaxscript' );
wp_localize_script( 'ajaxscript', 'ajaxobject',
    array( 
        'ajaxurl'   => admin_url( 'admin-ajax.php' ),
        'ajaxnonce' => wp_create_nonce( 'itr_ajax_nonce' )
    )
);
4
  • 5
    Simply add your inline JS inside the theme. That's exactly what wp_localize_script does anyway. With both methods, the variables are accessible from any script Oct 21, 2013 at 13:58
  • 3
    If you are in control of the scripts, how would you end up with a script in the head that was not enqueued properly? The notion of wp_localize_script is that you are making available to your script - which you are loading properly with wp_enqueue_script. In what case would you knowingly load script in the header file that needed these variables, rather than loading it through wp_enqueue_script? Oct 21, 2013 at 14:15
  • @cale_b : There is a script which is already included inside header.php and it contains lots of scripts which starts to break things when I try to enqueue that js file by wp_enqueue_script. I need to make an ajax call inside from that script file. So instead of breaking the functionality and fixing one by one I needed a quick solution. Even I am not sure which part of the site breaks because of the small change of 'wp_enqueue_script' :( Oct 21, 2013 at 14:32
  • Fair enough. Just as a tip, get Firebug for Firefox, and you can use the console to watch / see javascript errors. Invaluable tool for troubleshooting. Oct 21, 2013 at 15:44

4 Answers 4

28

Instead of using wp_localize_script in that case, you can hook your js variables at wp_head, that way it would be available to all js files like:

function my_js_variables(){ ?>
      <script type="text/javascript">
        var ajaxurl = '<?php echo admin_url( "admin-ajax.php" ); ?>';
        var ajaxnonce = '<?php echo wp_create_nonce( "itr_ajax_nonce" ); ?>';
      </script><?php
}
add_action ( 'wp_head', 'my_js_variables' )

Also to make it more error proof, it's advisable to use wp_json_encode() for the data.

add_action ( 'wp_head', 'my_js_variables' );
function my_js_variables(){ ?>
  <script type="text/javascript">
    var ajaxurl = <?php echo wp_json_encode( admin_url( "admin-ajax.php" ) ); ?>;      
    var ajaxnonce = <?php echo wp_json_encode( wp_create_nonce( "itr_ajax_nonce" ) ); ?>;
    var myarray = <?php echo wp_json_encode( 
       array( 
         'foo' => 'bar',
         'available' => TRUE,
         'ship' => array( 1, 2, 3, ),
       ) 
    ); ?>
  </script>
  <?php
 }
2
  • 4
    You should use json_encode here, for example: var ajaxurl = <?php echo json_encode( admin_url( "admin-ajax.php" ) ); ?>; Oct 22, 2013 at 20:33
  • Fine, i'll add it now onwards
    – Kumar
    Oct 23, 2013 at 5:40
14

You can export any data you want in the wp_head hook, as the answers above show. However, you should use json_encode to prepare the PHP data for exporting to JS instead of trying to embed raw values into JS literals:

function my_js_variables(){
    ?>
    <script>
    var ajaxurl = <?php echo json_encode( admin_url( "admin-ajax.php" ) ) ?>;
    var ajaxnonce = <?php echo json_encode( wp_create_nonce( "itr_ajax_nonce" ) ) ?>;
    var myarray = <?php echo json_encode( array( 
        'food' => 'bard',
        'bard' => false,
        'quux' => array( 1, 2, 3, ),
    ) ) ?>;
    </script>
    <?php
}
add_action ( 'wp_head', 'my_js_variables' )

Using json_encode makes it easier on yourself, and it prevents accidental syntax errors if your string includes any quote marks. Even more importantly, using json_encode thwarts XSS attacks.

1

I ended up doing this. It works now !! Thanks @dot1

function itr_global_js_vars() {
    $ajax_url = 'var itrajaxobject = {"itrajaxurl":"'. admin_url( 'admin-ajax.php' ) .'", "itrajaxnonce":"'. wp_create_nonce( 'itr_ajax_nonce' ) .'"};';
    echo "<script type='text/javascript'>\n";
    echo "/* <![CDATA[ */\n";
    echo $ajax_url;
    echo "\n/* ]]> */\n";
    echo "</script>\n";
}
add_action( 'wp_head', 'itr_global_js_vars' );
2
  • 8
    You should use json_encode instead of manually creating JSON. Oct 22, 2013 at 20:32
  • I am using json_encode now :) Thanks @WestonRuter !! Apr 5, 2018 at 13:32
1

While this isn't my finest work, this is another straight-forward way to accomplish putting data in the response:

<?php

/**
 * Add data to global context.
 *
 * @param string $name
 * @param mixed $value
 * @return mixed|array
 */
function global_js($name = null, $value = null)
{

    static $attached = false;
    static $variables = [];

    if (! $attached) {

        $provide = function () use (&$variables) {

            if (! empty($variables)) {

                echo("<script type=\"text/javascript\">\n\n");

                foreach ($variables as $name => $value) {

                    echo("    window['$name'] = JSON.parse('".json_encode($value)."');\n");
                    unset($variables[$name]);

                }

                echo("\n</script>\n");

            }

        };

        add_action('wp_print_scripts', $provide, 0);
        add_action('wp_print_footer_scripts', $provide, 0);

        $attached = true;

    }

    if (is_null($name) && is_null($value)) {
        return $variables;
    }

    return $variables[$name] = $value;

}

Add some JS data to the window context:

<?php

global_js('fruits', ['apple', 'peach']);

// produces: `window['fruits'] = JSON.parse('["apple", "peach"]');`

This will work for either the header scripts or footer scripts and won't repeat itself.

Your Answer

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

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