Recently on Twitter @iamcracks asked
Attention WordPress Wizards & Gurus. Is it possible to “get WordPress to write a custom field into a javascript variable”?
— source
While I wouldn’t be so bold as to claim I’m either a wizard or a guru, I happen to know the answer to @iamcracks question.
A while back I wrote a two part tutorial on using JavaScript the WordPress way, the code below builds on that. The first step is to load the JavaScript in functions.php using wp_enqueue_script()
as detailed in the earlier tutorial:
<?php
function brt_load_scripts() {
if (!is_admin()) {
wp_enqueue_script(
'brt-sample-script', //handle
'/path/2/script.js', //source
null, //no dependancies
'1.0.1', //version
true //load in html footer
);
}
}
add_action('wp_print_scripts', 'brt_load_scripts');
?>
This outputs the html required for the JavaScript when wp_footer()
is called in footer.php
Localising the script is done using the function wp_localize_script()
it takes three variables:
- $handle – (string) the handle defined when registering the script with wp_enqueue_script
- $javascriptObject – (string) name of the JavaScript object that contains the passed variables.
- $variables – (array) the variables to be passed
To pass the site’s home page and the theme directory, we’d add this function call below the wp_enqueue_script
call above:
<?php
...
wp_localize_script('brt-sample-script', 'brtSampleVars', array(
'url' => get_bloginfo('url'),
'theme_dir' => get_bloginfo('stylesheet_directory')
)
);
...
?>
The output html would be:
<script type='text/javascript'>
/* <![CDATA[ */
var brtSampleVars = {
url: "http://bigredtin.com",
theme_dir: "http://bigredtin.com/wp-content/themes/bigredtin"
};
/* ]]> */
</script>
<script type='text/javascript' src='/path/2/script.js?ver=1.0.1'></script>
Accessing the variables within JavaScript is done using the standard dot notation, for example brtSampleVars.theme_dir
to access the theme directory.
Using a post’s custom fields is slightly more complicated so I’ll write out the code in full:
<?php
function brt_load_scripts() {
if (is_singular()) {
wp_enqueue_script(
'brt-sample-script', //handle
'/path/2/script.js', //source
null, //no dependancies
'1.0.1', //version
true //load in html footer
);
the_post();
$allPostMeta = get_post_custom();
wp_localize_script('brt-sample-script', 'brtSampleVars',
array(
'petersTwitter' => $allPostMeta['myTwitter'][0],
'joshsTwitter' => $allPostMeta['joshsTwitter'][0]
)
);
rewind_posts();
}
}
add_action('wp_print_scripts', 'brt_load_scripts');
?>
Only pages and posts have custom fields so the check at the start of the function has become is_singlular()
to check the user is on either a post or a page, earlier we were testing if the user was anywhere on the front end. The arguments for wp_enqueue_script
have not changed.
the_post()
needs to be called to start the loop and initiate the $post object so the associated custom fields can be accessed in the following line and put in an array.
With the custom fields easily available, the information can then be passed to wp_localize_script()
as earlier demonstrated. The final step is to rewind the loop so next time the_post()
is called, from either single.php or page.php, the post data is available.
The html output from the sample above would be:
<script type='text/javascript'>
/* <![CDATA[ */
var brtSampleVars = {
petersTwitter: "@pwcc",
joshsTwitter: "@sealfur"
};
/* ]]> */
</script>
<script type='text/javascript' src='/path/2/script.js?ver=1.0.1'></script>