1

I need to pass a plugin's $atts variable to a javascript function, but I'm not sure how to do it. The javascript function needs the shortcode's php latitude variable in order to build the map.

My plugin looks like this:

<?php
/*
Plugin Name: Lax Google Map Plugin
Plugin URI: http://www.mysite.com
Description: Makes Map
Version: 1.0
Author URI: http://www.mysite.com
*/

function lax_google_map_init() {
    wp_enqueue_script('google-maps', 'http://maps.googleapis.com/maps/api/js?sensor=false');
    wp_enqueue_script('lax_google_map_script', plugins_url('js/lax_google_map_script.js', __FILE__), array('google-maps','jquery'));
}

add_action('init', 'lax_google_map_init');


function lax_google_map_maker($atts,$content=null) {

    $atts = shortcode_atts( array(
        'width' => '600', 
        'height'=>'600',
        'latitude'=>'38.9205'
        ),
        $atts);


    $output .= '<div id="map_canvas" style="width:'. $atts['width'] .'px; height: '. $atts['height'] .'px; border:1px solid black;"></div>';

    return $output;
}

 add_shortcode('lax-google-map', 'lax_google_map_maker');

?>

The javascript file looks like:

jQuery.noConflict();

jQuery(document).ready(function($) {

  var latlng = new google.maps.LatLng(39.73, -76.02);
  var myOptions = {
      zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };

      var map = new google.maps.Map(document.getElementById("map_canvas"),
        myOptions);

});

So I need to replace '39.73' with something like:

pseudo-code:

var latlng = new google.maps.LatLng( + $atts['latitude'] + , -76.02);

Also, the javascript gets loaded before the shortcode $atts are available. What's the best way to change it?

Sorry, for the basic questions. I'm learning how to write a plugin.

Any suggestions?

Thank you.

-Laxmidi


UPDATE:

If I add this:

$params = array (
        'latitude'=>  '39.01',
        'longitude'=> '-76.02'
        );

    wp_localize_script('lax_google_map_script', 'lax_map_params', $params);

to lax_google_map_init()

And I add:

var latlng = new google.maps.LatLng( lax_map_params.latitude, csf_crime_map_params.longitude);

to my javascript function, the map works. How would I replace '39.01' with the $atts[latitude] and -76.02 with $atts[longitude] ? I'm still learning about scope in php. Thank you.

1
  • Btw: You don't build your markers through the Map object. You have to use some function to build & update a markers array. It's inside your function something like (right after the map init): for ( var i=0; i < mapsInitMarkers.length; i++ ) { createMarkerFunction( /* put markersInitArray[ i and other values ] here */ ); }
    – kaiser
    Commented Sep 15, 2011 at 16:45

3 Answers 3

3

You need to have some initial (maybe global) js var markers_array = [];. Then use an ajax callback function to bump your markers into that array.

Register your scripts

// Define
$root_url = plugin_dir_path(); // Example path
$ajax_nonce = 'your_nonce';
$ajax_nonce_val = 'your_val';

// Ajax
wp_register_script( 'json2', false, false, false, true );
wp_enqueue_script( 'json2' );

wp_enqueue_script( 
     'ajax-script'
    ,"{$root_url}js/ajax_json.js" // your ajax callback script that handles the request (inside a /js folder)
    ,array( 
        'json2'
     )
    ,false
    ,true 
);
wp_localize_script( 
     'ajax-script' 
    ,'ajax_object' // YOUR MAIN DATA OBJECT
    ,array( 
         'ajaxurl'          => admin_url( 'admin-ajax.php' )
        ,$ajax_nonce    => wp_create_nonce( $ajax_nonce_val ) 
    ) 
);

The initial Markers

// inside some <script> part: You need the following php function to build your markers array:
// This js array will be used by your custom build markers js function to build the initial markers. It can also be used to update markers and overlays.
var mapsInitMarkers = <?php echo build_markers_array(); ?>;

// Markers builder callback function for init js-var
function build_markers_array()
{
    $output = '';
    $markers = array( /* DEFINE MARKERS HERE */ );
    foreach ( $markers as $marker )
    {
        // id, lat, lng, name
        $output .= "[
             {$marker['ID']}, 
             {$marker['lat']}, 
             {$marker['lng']}, 
            '{$marker['name']}', 
        ],";
    }
    $output = substr( $output, 0, -1 ); // get rid of last comma
    $output = "[{$output}]";

    return $output;
}

The Ajax Callback function

function ajax_cb_fn() 
{

    check_ajax_referer( 'referer_name', $ajax_nonce ); // needed if performed some update via some ex. form

    $output = ''; // do stuff here - example, use build_markers_array(); with some input to update your markers

    $response = json_encode( array( 
         'data' => $output 
    ) );
    header( "Content-Type: application/json" );
    echo $response;

    exit();
}

The data handling inside ajax_json.js

Now you can write some document.ready() function inside your new ajax json handling file. In there you can access your data via the ajax_object javascript object. You could use $.post() to perform data handling via forms, or else. You can also bump your markers into some createMarkers js function which you could also use to build your initial array (you need to handle the marker creation somewhere.

Why you shouldn't add this data as mark-up element attributes

Mark up get's rendered by the browser, data just processed. Just imagine how your div will look like if you drop hundreds of lat/lng atts in there. In a short time you'll need to drop support for device browsers and netbook laptops, tablets, etc.

3
  • Hi @kaiser, Thank you for your very detailed solution. I'm still learning php/javascript (and unfortunately, I don't know anything about JSON). Yout skills are much more advanced than mine. I'll have to study your solution and the languages some more. I've updated my question a bit. If I use Toby's idea of using wp_localize_script, how can I pass $atts[latitude] from one php fucntion, lax_google_map_maker() function to the other php lax_google_map_init(). Thank you.
    – Laxmidi
    Commented Sep 15, 2011 at 19:06
  • n/p. As I said: You don't drop your lat/lng pair into the maps object itself. The lat/lng inside the init maps function is the center of the map. Not the marker. If you want to use more than one marker, then you need a) a function to construct a marker object inside your google map (search on ... google) and b) use that function inside your map init js function - See "the initial markers". This builds the js array of markers that you want to add to your map. Then run a function inside the js google map init function to create each markers inside the array.
    – kaiser
    Commented Sep 15, 2011 at 23:48
  • See here how to construct a var marker. This fn builds a single marker. Then you need the foreach js loop as written in the comment to the Q, where you attach this marker function to each marker data set inside your initial js marker array.
    – kaiser
    Commented Sep 15, 2011 at 23:50
2

You could use wp_localize_script to take your PHP variables and put them into JavaScript.

7
  • I don't like @Toby solution, because using wp_localize_script will make this site "uncacheable" What if there were 1000 single posts with these maps? For each one WP will generate different javascript code. Commented Sep 15, 2011 at 16:36
  • No, it won't. See my A. You have a single js object to handle your ajax requests and else. Just handle the data inside there (update, clear, init, etc.). The rest is plain simple SQL queries or just meta data (in every case php & db stuff). Furthermore shouldn't this be an answer. It's a comment on Toby answer, so you could use the comment link below his A.
    – kaiser
    Commented Sep 15, 2011 at 16:39
  • first, I don't see comment link below Toby's and yours answers - don't know why. Commented Sep 15, 2011 at 16:45
  • Hm, maybe it's because of your reputation? Normally you have link | edit | flag next to the voting arrows and right underneath you got add comment. Should normally be under each answer. (Btw: You just used it to write back to me ;)
    – kaiser
    Commented Sep 15, 2011 at 16:46
  • I can comment on comments, not on answers :) But returning to your A. Your solution is OK, but isn't it a little bit complex? It requires additinal ajax request just to read few values: lat/lng. I assumed that Laxmidi wants to display simple google map, so embedding map params as div attributes will be simple enough. Jquery will then "read" this values right after dom loaded and maps will be displayed and centered to the requested position. Commented Sep 15, 2011 at 16:52
0

I would do this that way:

in plugin code add data-latitude attr to div#map_canvas:

$output .= '<div id="map_canvas" data-latitude="'.$atts['latitude'].'" style="width:'. $atts['width'] .'px; height: '. $atts['height'] .'px; border:1px solid black;"></div>';

and in javascript allow JQuery to read attribute data-latitude from div#map_canvas

var latlng = new google.maps.LatLng($('#map_canvas').attr('data-latitude'), -76.02);

Probably you will need a similar code snippets for longitude..

use attributes prefixed with "data-" in order to have a html5 validation.

Hope it helps

1
  • Hi Maciej Kus, Thnak you very much for your solution. I didn't know about the -data prefix in HTML5. I learned something new. I made my example simple, but eventually, I would like to put lots of markers on the map, so I don't think that that marking up the div will work in my case. If you have other idea, I'd love to hear them. Thank you.
    – Laxmidi
    Commented Sep 15, 2011 at 18:37

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.