Using Multidimensional Arrays with wp_localize_script

Recently, I was working on a plugin that uses a custom post type to create Markers for Google Maps. Since interaction with Google Maps requires use of javascript, I needed to find a way to send post data and postmeta for the posts to be used in javascript to create Google Map Markers. When each post of custom type ‘mkm-gmap-cpt’ is saved to the database, the address custom field is geocoded and values for ‘latitude’ and ‘longitude’ are saved as postmeta for the post. To create Google Maps Marker for these posts, I needed to be able to send the values for ‘latitude’ and ‘longitude’ to the javascript for processing. Additionally, I wanted to send the ‘post_content’ to the javascript to be used in the info window for the marker.

As is often recommended, I used wp_localize_script to send my variables to javascript. Using wp_localize_script is quite simple with the following three steps.

  1. Enqueue your script that will use the variables using ‘wp_enqueue_script’
  2. Collect your parameters in an array
  3. Call wp_localize_script to send the parameters to the script that will use them

For my plugin, I first enqueued the script that would be handling the creation of the Google Map and corresponding Markers.

1
2
3
4
5
6
wp_register_script( 
	'mkm-gmap', 
 	 plugins_url('js/mkm-gmap.js', __FILE__), 
 	 array('jquery') 
);
wp_enqueue_script('mkm-gmap');

I then gathered data from my posts and collected it in an array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Query the database for the custom post
$args = array(
	'post_type' => 'mkm-gmap-cpt',
	'posts_per_page' => -1
);
$query = new WP_Query($args);
 
while($query->have_posts())
{
	$query->the_post();
	global $post;
 
	// Set the params
	$params[$post->ID] = array(
		'latitude' => get_post_meta($post->ID, 'latitude', true),
		'longitude' => get_post_meta($post->ID, 'longitude', true),
		'description' => $post->post_content
	);
}

The $params array is a multidimensional array that contains latitude, longitude, and description values for each post. Up to this point, everything was copacetic. I next tried to send the $params array to the script using wp_localize_script. This is where things broke down. Initially, I used the following code.

1
wp_localize_script('mkm-gmap', 'markers', $params);

wp_localize_script creates a JSON encoded object that will appear in a script> tag before the dependent script is called. It creates the variables that will be used by the script that is specified. When I checked the result of this in my javascript, I found the following.

1
2
3
4
 var markers = {
 
};
markers = {"66":{"latitude":"25","longitude":"-120","description":"A test description"},"65":{"latitude":"65","longitude":"35","description":"Here is something great."},"59":{"latitude":"63","longitude":"72","description":"This is my home"}};

Instead of sending a JSON encoded object containing the values of the $params array to the javascript, it instead sent the word “Array” with the key being the post ID. This certainly was not helpful. It turns out, when you send an array of values to wp_localize_script, WordPress simply adds commas, line breaks and escapes the data for use in javascript. It completely ignores the values stored as an array. Fortunately, there is a loophole. In the function that ultimately handles the data from the wp_localize_script function, it will allow any value with the key l10n_print_after to pass without modification. You must be careful when using this method as WordPress does not escape the data for you, so you need to be careful what you send to it. To remedy my situation, I used the following code to send the $params array.

1
2
3
4
5
$params = array(
	'l10n_print_after' => 'markers = ' . json_encode($params) . ';'
);
 
wp_localize_script('mkm-gmap', 'markers', $params);

Instead of printing the word “Array” as output, this code properly encoded my $params array for use in javascript. It produced the following.

1
2
3
4
var markers = {
 
};
markers = {"66":{"latitude":"25","longitude":"-120","description":"A test description"},"65":{"latitude":"65","longitude":"35","description":"Here is something great."},"59":{"latitude":"63","longitude":"72","description":"This is my home"}};

By setting the second argument of the wp_localize_script function to ‘markers’ and sending an array with the key l10n_print_after as the third argument, two things happen. First, an empty object with the ‘markers’ is created.

1
2
3
var markers = {
 
};

Second, the value that was given the key l10n_print_after is printed. In this case, I intentionally set the first part of this string to be ‘markers = ‘ so that I would assign the previously created ‘markers’ object to the JSON encoded object that was assigned the l10n_print_after key in the $params array. In the end, a useable object that contains the data needed for the markers is printed.

1
markers = {"66":{"latitude":"25","longitude":"-120","description":"A test description"},"65":{"latitude":"65","longitude":"35","description":"Here is something great."},"59":{"latitude":"63","longitude":"72","description":"This is my home"}};

Using this method to JSON encode multidimensional arrays makes creating variables in PHP and sending them to javascript for use in exciting, interactive web apps a breeze. While I initially thought that this function is limited to using unidimensional arrays, I was pleasantly surprised to find that the WordPress dev team built in a loophole that allows for one to send any data to the javascript and make this function infinitely flexible.

This article was authored by:

I am a Senior Web Engineer at 10up LLC. While I am well versed in general web development, WordPress is my bread and butter. I enjoy working on WordPress projects, writing plugins, and helping other learn about appreciate how incredible the WordPress software is. After about 8 years doing web development, I have finally launched my own website. I’d like to think it’s because I finally feel that I have something to say, but really, it’s actually because I was finally able to design a theme that I did not loathe.

Zack Tollman has authored 6 posts.Visit Website

Showing 2 Comments

  • Just to check – this work-around is only necessary for non-associative arrays? I’ve used wp_localize_script with multi-dimensional (associative) arrays in my plug-ins without any problems – the array becomes an object, with keys the property of that object.

    REPLY
  • I realise that this post is old was valid when it was posted, but to update my previous comment – nested arrays are now supported (since 3.3, I think). I’ve verified this myself, but there is also this thread from <a href=”wp http://old.nabble.com/congratulations-on-wp_localize_script-td33498029.html”>wp-hackers</a>. 
     
    Sorry for any confusion. 

    REPLY

Add Your Voice: