A while back, I wrote a post detailing why it was a bad idea to generate Javascripts using PHP in WordPress plugins. In that post, I mentioned a couple of better ways to do it.

At the time, I didn’t know about the third, and best way, to accomplish this. Mike’s comment over there reminded me of it. WordPress has it built in.

If you already know about wp_localize_script, you can stop reading now.

The wp_localize_script function was made in order to allow for WordPress translations to be able to also translate some of the JS files inside WordPress. Thus the name “localize”. The way it works is to load up the translated versions of text from the translation files and then include them into the resulting HTML output as a Javascript object. The scripts then use that object to produce any text output they need to produce.

Turns out that’s really similar to our goal of sending arbitrary parameters from WordPress to be used by Javascript code.

How to do it:

1. Make your script static (instead of generated) and enqueue your script as per normal. Example:

wp_enqueue_script('my-script','/path/to/whatever.js',…);

No real changes there. You’ll have to come back and modify your script to use these parameters it’s getting passed, but we’ll get to that in a minute.

2. Build an array of your parameters that you want to send to the script.

$params = array(
  'foo' => 'bar',
  'setting' => 123,
);

Note that my parameters are simple examples, but this is PHP code. You can get your parameters however you like. Such as get_option to pull them from the database, perhaps.

3. Call wp_localize_script and give your parameters a unique name.

wp_localize_script( 'my-script', 'MyScriptParams', $params );

What this will do is make WordPress output an inline script with your parameters (properly encoded) just before the enqueue outputs the script tag that loads your script in the first place. So then those parameters will be available to your script as an instance of an object with “MyScriptParams” (from my example).

This means that Javascript code can now reference them as attributes of the name you gave.

So, step 4. Modify your script to use those parameters. In my example, I used “MyScriptParams” and the parameter names are “foo” and “setting”. In my Javascript code I can use them as “MyScriptParams.foo” and “MyScriptParams.setting”.

Much cleaner. One static and unchanging JS file to cache. Parameters get put into your HTML itself as a one-liner. You can deal with the parameters using a normal PHP array before passing them over. No need to screw around with generating Javascript from PHP or looking for wp-load or even messing with tricky actions.

Perfect.

Shortlink:

21 Comments

  1. [...] Note: There is a followup post to this one, which details an even better way than the two given below: http://ottopress.com/2010/passing-parameters-from-php-to-javascripts-in-plugins/ [...]

  2. [...] Passing parameters from PHP to Javascripts in plugins » Otto on WordPress. Share and [...]

  3. Otto,

    Thanks for pointing me this direction. Unfortunately, after spending the day coding the construction of two arrays that are three levels deep, I have discovered “wp_localize_script only supports arrays with one level for translation purposes.” Is there an alternative that would allow me to pass these complex arrays via wp_localize_script or something similar?

    • If you’re needing to pass extremely complex structures, you should hook to wp_head and output your own script tags and variables. You can use json_encode() to convert complex PHP structures into Javascript capable structures.

  4. Hi Otto,

    I think I may have found the one case where including wp-load.php is necessary. Hopefully I’m wrong because I hate it and don’t want to include it. I’m making a plugin that needs to use a rest api to retrieve files and everything needs to be OAuth signed, etc. I want to pull files from this service and throw them at the browser to display them. So at the top of my plugin I have this horrible thing:

    if (isset($_GET['display'])) {
    require_once( "../../../wp-load.php" );
    require_once( plugin_dir_path( __FILE__ ) . "/includes/connection.php");

    $connection = new Connection(
    get_option( 'consumer_key' ),
    get_option( 'consumer_secret' ),
    get_option( 'access_token' ),
    get_option( 'access_token_secret' ));

    $metadata = json_decode($connection->get( $_GET['display'] ));

    header("Content-Type: " . $metadata->{ 'mime_type' });
    echo $connection->get( $_GET['display'],null,true);

    exit;
    }

    Now I need those keys and access tokens for OAuth. I can’t put them in a file and read them because they need to be secret, I can’t bake them on a script or url on a page since they need to be secret. The plugin puts them into the database using the standard options calls. So I need to have PHP look these values up somehow so we can sign our API request for OAuth. And that’s where I’m stuck. I have no guarantees for any access to a database other than through the WordPress API.

    Sorry for so much spam but it’s really bugging me and I’m hoping you will be able to see something blindingly obvious I’m missing to not have to includ wp_load!

    Many thanks!

  5. [...] variable to JavaScript for your WordPress plugin, go through this very good post by Otto – Passing parameters from PHP to Javascripts in plugins This is a very safe and straightforward way to pass your PHP variables into your JavaScript.  This [...]

  6. Hi Otto,

    Great article, it surely put me in the right direction for what i’m looking for. I hope you have an anwers to the question remaining:

    in trying to pass data as shown above, all is well!
    im now trying to pass data from a widget to the array. Problem is that all data put into the widget option is a multidimensional array, where the data set is depending on the instance of the widget (allways multiwidget). ie the title of a widget is inside [2][title] or [3][title]. how can i pull the right data?

    • Pull the data out of the multidimensional array and put it into a regular one dimensional array. Then send it to the script. JS can’t cope with multidimensional arrays. Simplify your data before sending it to the script.

  7. Great solution! :) I found another way ( on inchoo.net) to passing parameters… for example creating javascript file in php with “content-type: application/x-javascript”… but i think will use wp_localize_script (it was created for translate javascript content?)
    thanks for share!

  8. I have a error from the console when trying to do this : “php_params is not defined” in the /js/script.js file.

    i don’t what i did wrong

    // inside functions.php
    wp_enqueue_script(‘myscript’, get_stylesheet_directory_uri().’/js/script.js’, array(‘jquery’));

    // inside single.php
    ”,
    1 => ”,
    2 => ”
    );

    wp_enqueue_script(‘myscript’);
    wp_localize_script(‘myscript’, ‘php_params’, $params);
    ?>

    // and inside /js/script.js
    alert(php_params);

  9. sorry i forgot to put the markup in the previous message. here it is again :

    I have a error from the console when trying to do this : “php_params is not defined” in the /js/script.js file.

    i don’t what i did wrong

    // inside functions.php
    wp_enqueue_script(‘myscript’, get_stylesheet_directory_uri().’/js/script.js’, array(‘jquery’));

    // inside single.php
    $params = array(
    0 => '',
    1 => '',
    2 => ''
    );

    wp_enqueue_script('myscript');
    wp_localize_script('myscript', 'php_params', $params);

    // and inside /js/script.js
    alert(php_params);

    • Ok it’s necessary that the array declaration and the wp_localize_script stay before wp_head() (so inside single.php, it has to be before the header.php call. )

      now it’s working.

  10. I’m making a widget and I need to send parameters from the widget code to javascript file… I put the wp_enqueue_script code line before the class code and wp_localize script in a function from the class, beacuse that where i get the paramaters from the instance, but It doesn’t send the parameters.. I must be doing something wrong… where should I put wp_enqueue_script and wp_localize_script?

  11. If only something similar could be done for css…

  12. Is there a way to preserve boolean values with wp_localize_script?

  13. Very nice man. Thanks!

  14. Hi All,
    I am trying to use jqgrid in a plugin. jqgrid relies on the parameter url:’external.php’ file.

    I can not think any other way than ussing wp-load.php to allow the external.php file access the wpdb functions.

    Does anyone knows how to implement jqgrid without using wp-load.php….any sample much appreciated.
    Thanks.

    • jqgrid doesn’t rely on having an external PHP file, it relies on having a URL to talk to in order to get the data. So you give it the URL to the admin-ajax.php file, along with a query parameter, which you catch in your plugin and use to trigger the proper output.

  15. [...] variable to JavaScript for your WordPress plugin, go through this very good post by Otto – Passing parameters from PHP to Javascripts in plugins This is a very safe and straightforward way to pass your PHP variables into your [...]

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Need to post PHP code? Wrap it in [php] and [/php] tags.