0

I'm currently working on an interactive map (using OpenStreetMap and OpenLayers), which works as I want on a local website (see this screenshot : https://i.sstatic.net/Ev08B.jpg).

My code uses Html, Php and JavaScript.

I wish to integrate this interactive map into a page of my WordPress website. For the Php part, it's simple, I use the shortcode technique. I already tested it, it works, including the communication with the database.

However, the map itself is a JavaScript script. I would love to use the "enqueue_script" technique, but the problem is that my script contains some Php, used to pass a json array containing basically the info to place the markers on the map.

The question is : is that possible to include this script on a WordPress page (the same as the one where I include the Php), and if so, how could I do that ?

Here is the (simplified) Php code. It works, but it might help you guys to understand what I want to do :

function register_shortcodes(){
    add_shortcode('fidu-display-map', 'display_map');
}
add_action( 'init', 'register_shortcodes');

function display_map(){

    generate_html();
    get_search_results();
    generate_map();
}

function generate_html(){

    echo "<div id=\"basicMap\" style=\"width: 100%;
            height: 100%; coordinates
            margin: 0;\"></div>";
}

function get_search_results(){

    global $wpdb;
    global $result;

    $result = $wpdb->get_results("SELECT * FROM search_results;", ARRAY_A);
}

function generate_map(){
    global $result;
    $res_lon = array();
    //[... other declarations]
    $res_link = array();
    foreach ($result as $row) {
        array_push($res_lon, $row['lon']);
        //[... other pushs]
        array_push($res_link, $row['societyLink']);
    }
    $search_result = array(
        $res_lon,
        //[... other merging]
        $res_link
    );
}

Now here is the JavaScript, with the Json part that causes me some problems because it depends on the Php above :

<script>

    document.addEventListener("DOMContentLoaded", function()
    {
        init();
    }, false);

    var map;

    function init(){
        map = new OpenLayers.Map('basicMap');

        var mapnik = new OpenLayers.Layer.OSM();
        var fromProjection = new OpenLayers.Projection("EPSG:4326");   // Transform from WGS 1984
        var toProjection   = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
        var centerPosition = new OpenLayers.LonLat(-85.00,38.00).transform( fromProjection, toProjection);
        var zoom           = 5;

        map.addLayer(mapnik);

        map.setCenter(centerPosition, zoom);


        addPoints(map);
    }

    function addPoints(map){
        var fromProjection = new OpenLayers.Projection("EPSG:4326");   // Transform from WGS 1984
        var toProjection   = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
        //get positions from the search result from the database
        var positions = <?php echo json_encode($search_result) ?>;
        var infos = <?php echo json_encode($search_result) ?>;

        var coordinates = new Array();
        var pointStyle = {  externalGraphic: 'images/marker-blue.png',
            graphicWidth: 21,
            graphicHeight: 25,
            graphicYOffset: -24};

        // Layer
        var pointsLayer = new OpenLayers.Layer.Vector("Points Layer");


        // Add points to the layer
        for(i=0;i<positions[0].length;i++){
            //coordinates.push(new OpenLayers.Geometry.Point(positions[0][i], positions[1][i]).transform(fromProjection, toProjection));
            var pointFeature = new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(positions[0][i], positions[1][i]).transform(fromProjection, toProjection),
                {description : infos[2][i]+'<br>'+infos[3][i]+'<br>'+infos[4][i]+' - '+infos[5][i]+'<br>'+infos[6][i]+'<br>Link: <a href="'+infos[7][i]+'">'+infos[7][i]+'</a>'},
                pointStyle
            );
            pointsLayer.addFeatures(pointFeature);
        }

        map.addLayer(pointsLayer);

        //Add a selector control to the vectorLayer with popup functions
        var controls = {
            selector: new OpenLayers.Control.SelectFeature(pointsLayer, { onSelect: createPopup, onUnselect: destroyPopup })
        };

        map.addControl(controls['selector']);
        controls['selector'].activate();
    }

    function createPopup(feature) {
        feature.popup = new OpenLayers.Popup.FramedCloud("pop",
            feature.geometry.getBounds().getCenterLonLat(),
            null,
            '<div class="markerContent">'+feature.attributes.description+'</div>',
            null,
            true,
            function() { controls['selector'].unselectAll(); }
        );
        map.addPopup(feature.popup);
    }

    function destroyPopup(feature) {
        feature.popup.destroy();
        feature.popup = null;
    }

</script>

1 Answer 1

1

What you can do, is place those variables out of your javascript function. So for example you can put it in the <head> like:

var mapPoints = {
    positions: <?php echo json_encode($search_result) ?>,
    infos: <?php echo json_encode($search_result) ?>
}

Now, if you create a javascript file and use enqueue_scripts to add it to your page, you can still access mapPoints in your functions.

Sign up to request clarification or add additional context in comments.

5 Comments

I'm not sure to understand... If I put these variables in the <head>, I have the same problem because I cannot give them to WordPress like that, can I ?
You can't combine php and javascript in a .js file. However, you can put those variables in the head (yes, you cannot use enqueue_scripts for this), but this way, all of the other parts of your javascript can go into a simple .js file and you can use enqueue_scripts to add it to your page. This is good, because the actual logic is in a separated javascript file, and the variables in the head are the "bridge" between your php and javascript code, and only that is extracted into the head.
Ok I understand now, thanks for this answer. However, I'm integrating this in WordPress, which means the header is already done. My shortcode is going in a <div> dedicated to the content. Do you think I could put those variables into a <div> as well ?
If those variables are above of the actual javascript file which uses enqueue_scripts, then they will be available the same way as if they were in the head.
That was more complicated than I expected (because there were other problems in my code), but now I managed to get everything to work. THe solution to this specific question is exactly what you told. Thanks a lot for your help !

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.