How to pass custom Wordpress fields into mapbox-gl js to create markers on map?

Viewed 472

I'm trying to create a map plotting different points using Mapbox and Wordpress. In Wordpress I created a custom post type with the coordinates stored in custom meta fields. The fields are all setup, but I am having trouble passing them into the javascript in my php template.

I tried using a loop, but can't use it as the coordinates need to be stored inside the javascript. Seems like storing the custom meta fields in a geoJSON is the only solution.

Here is what the Mapbox code should look like, the coordinates and title should come from the posts and custom fields though:

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/coptmarketing/cjvi7hc4602dk1cpgqul6mz0b',
    center: [-76.615573, 39.285685],
    zoom: 16 // starting zoom
});

var geojson = {
    "type": "FeatureCollection",
    "features": [{
            "type": "Feature",
            "properties": {
                "title": "Shake Shack"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [-76.609844, 39.286894]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "title": "Starbucks"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [-76.619071, 39.286649]
            }
        }
    ]
};

My PHP looks like this to get the custom fields and transform it into JSON:

<?php $args = array( 
    'post_type' => 'places', 
    'post_status' => 'publish', 
    'nopaging' => true 
);
$query = new WP_Query( $args ); // $query is the WP_Query Object
$posts = $query->get_posts();   // $posts contains the post objects

$output = array();
foreach( $posts as $post ) {    // Pluck the id and title attributes
    $output[] = array(
        'id' => $post->ID,
        'title' => $post->post_title,
        'address' => get_post_meta($post->ID,'ci_cpt_adresse', true),
        'longitude' => get_post_meta($post->ID, 'ci_cpt_adressex', true),
        'altitude' => get_post_meta($post->ID, 'ci_cpt_adressey', true) 
    );
    }
$data = json_encode(['placelist' => $output]);
?>

I then tried processing the data via this script. However, it doesn't return anything:

<script>
var placeJson = data;

var stores = {
          "type:" "FeatureCollection",
          "features:" [],
        };

        for (i = 0; i < placeJson.placelist.length; i++) {

          geojson.features.push({
            "type": "Feature",
            "geometry": {
              "type": "Point",
              "coordinates": [placeJson.placelist.[i].altitude, placeJson.placeList[i].longitude]
            },
            "properties": {
              "title": placeJson.placelist.[i].title
            }
          },);
        }
</script>    


<script>        
    stores.features.forEach(function(store, i){
      store.properties.id = i;
    });
</script>

I already found a possible solution here, but don't understand how to get it into geoJSON: How to pass custom fields into mapbox-gl js to create points on map?

2 Answers

you can do so via wp_localize_script (please note below code is an example and needs to be altered to work in your case)

wp_enqueue_script( 'my_mapbox', get_template_directory_uri() . '/js/mabox.js' );
 
$dataToBePassed = array(
    'home'            => get_stylesheet_directory_uri(),
    'pleaseWaitLabel' => __( 'Please wait...', 'default' )
);
wp_localize_script( 'my_mapbox', 'php_vars', $datatoBePassed );

and then in your script call to the localized object https://code.tutsplus.com/tutorials/how-to-pass-php-data-and-strings-to-javascript-in-wordpress--wp-34699

Basically, there are three solutions here. Which one is relevant for you highly depends on your use case ofcourse!

  1. Run your custom post query in the function that you use to enqueue the script in and localise a variable in wp_localize_script with the data from the Query (Jasper B his solution above :) )

  2. Inline the php with the script. PHP code is on same page as inlined script (hacky but quick for testing). Something like this (correct the closing php):

    var data = <?php $data ?"> // TODO Correct this pls! I can't write it here. As long this is encoded, it should provide you with an array of data, just console.log it to see if it's correct.

  3. You can create an endpoint with Ajax or with Wordpress REST, and in your JS file query the data and display it. Here is some more info on how to set up an Ajax Get request

Related