Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'd like to use the $atts variable from the lax_google_map_maker() function in lax_google_map_init(). How do I access it? I tried to 'globalize' it, but for some reason it didn't work.

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'));

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

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

add_action('init', 'lax_google_map_init');


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

     $atts = shortcode_atts( array(
        'latitude'=>'38.9205',
               'longitude'=>'-77.04505920410156'),
        $atts);

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

    return $output;
}


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

My goal is to set the $params variable using the shortcode's $atts. As I understand it, I have to keep the $params variable in the same function as the wp_enqueue_script line and the wp_localize_script line. Otherwise, I would break it out into a new function and pass in the $atts as a parameter.

If there were a way to pass in $atts to function lax_google_map_init, I would be golden.

I've tried everything that I can think of. Looking forward to hearing your good ideas.

share|improve this question
    
Don't "globalize" it, pass it as an argument to the other function! –  onetrickpony Sep 15 '11 at 21:11
    
@One Trick Pony, Thank you for your message. How do I pass $atts as an argument when lax_google_map_init() is called by add_action('init'...)? I need the $atts in order to set the $params. I can't move $params into another function because I can't add a parameter to lax_google_map_init(). I'm a little stuck. Any suggestions? Thank you. –  Laxmidi Sep 15 '11 at 22:54
    
This is a PHP question, not a WordPress question. –  Chip Bennett Sep 16 '11 at 1:37
    
Hi @Chip Bennett, I think that it's a WP question that concerns PHP. If it were straight PHP, I would just pass the $atts as a parameter in a new function as One Trick Pony suggested. But, I don't understand WP well enough to know how to break it out into another function when I've got this: add_action('init', 'lax_google_map_init'); and the wp_localize_script lines. It's a tough one. Thank you. –  Laxmidi Sep 16 '11 at 3:12
1  
I do think this is a WP related question, however, I don't think the phrasing of the question is quite right. Perhaps, "How to pass arguments from a shortcode into a javascript function" would be better? Dealing with shortcodes, actions, enqueued scripts, and jQuery no conflict stuff is pretty WordPressy imho. This wasn't clear from the original title of the question, but was revealed working out the answer. –  goto10 Sep 17 '11 at 19:31

1 Answer 1

up vote 1 down vote accepted

G'day mate ;)

I've done this by outputting the variables within a script tag right within the body. I played around with your code and came up with this solution:

function lax_google_map_init() {

  // Don't bother loading the scripts if we're in the admin area
  if ( is_admin() ) {
    return;
  }

  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( 'wp_print_scripts', 'lax_google_map_init' );


function lax_google_map_maker( $atts, $content = null ) {
    // Default params.
    $atts = shortcode_atts( array ( 
      'latitude'=>'-25.068302',
      'longitude'=>'-130.095581',
      'zoom' => 18,
      'id' => 'map_canvas',
      'width' => '500px',
      'height' => '500px'
      ), $atts );

    $output .= '<div id="' . esc_attr( $atts['id'] ) . '" style="width:' . esc_attr( $atts['width'] ) . '; height: '. esc_attr( $atts['height'] ) .'; border:1px solid black;"></div>';
    $output .= 
    "<script>" . "\n" . 
      "var lax_map_params_" . $atts['id'] . " = " . json_encode( $atts ) . "; lax_google_map_maker_js( lax_map_params_" . $atts['id'] . " );" . "\n" . 
    "</script>" . "\n";  

    return $output;
}
add_shortcode( 'lax-google-map', 'lax_google_map_maker' );
// [lax-google-map latitude='-66.552635' longitude='84.137421' zoom='12'] // no id, usees default
// [lax-google-map latitude='65.032366' longitude='-376.747681' zoom='12' id="map_1"] // id specified.  Will be used in js variable name, so no hyphens or other chars that will break js variable names allowed.
// [lax-google-map latitude='-25.068302' longitude='-130.095581' zoom='12' id="map_2" width="200px" height="200px"] // custom dimensions
// [lax-google-map latitude='-34.397' longitude='150.644' zoom='12' id="map_3"]

Here is the lax_google_map_script.js file:

jQuery(document).ready(function($) { 
  // alert ('hi');
});

function lax_google_map_maker_js( args ) {

  // Default js args.  Args passed to function will override these.
  var default_args = {
    latitude :  -34.397,
    longitude :  150.644,
    id : 'map_canvas',
    zoom : 8
  }; // @link http://www.openjs.com/articles/optional_function_arguments.php

  for ( var index in default_args ) {
    if ( typeof args[index] == "undefined" ) {
      args[index] = default_args[index];
    }
  }

  var latlng = new google.maps.LatLng(args['latitude'], args['longitude']);

  var myOptions = {
    zoom: parseInt( args['zoom'] ),
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

    // alert ('hi'); // just showing that you can use jQuery with the dollar method in here.

  var map = new google.maps.Map(document.getElementById( args['id'] ), myOptions);  
}

Notes: localize_script can only do js arrays 1 level deep, so personally I didn't go that route (source - see comments).

I learned the inline js variable trick from a great WPSE answer by Bainternet.

I do think the best way to do this is by putting everything in a class, and outputting the concatenated js from a property wrapped in properly formatted js tags fired on the wp_footer action triggered by a method that checks to see if the shortcode was used. That's something to consider for future revisions. Optimal Script Loading

In my original answer, I removed the jQuery bits because jQuery wasn't used in the script. jQuery.noConflict(); isn't needed when using WP's included version of jQuery. In my revised answer, I left the jQuery stuff at the top, but moved the lax_google_map_maker_js() function out of that block, because otherwise, an error occurs.

share|improve this answer
    
Awesome answer! Thank you very much for your kind help. I never would have thought of concatenating the js script in the $output. Thank you for mentioning the localize_script pitfall. I want to understand your solution thoroughly. As I understand it, this bit jQuery.noConflict(); jQuery(document).ready(function($) { } isn't needed? Do I need to worry about this script conflicting with other scripts? Multi-instance friendly: As long as I only have one lax-google-map shortcode per page, then it should work okay? As I understand it, it will only crash if I have multiple maps on one page. –  Laxmidi Sep 16 '11 at 18:17
    
Sorry, I ran out of space. Thank you for including the open.js link explaining what you were doing in the "for in" loop. Do I need to set default values for the $atts in php if we there are defaults set in default_args in the js script? If I wanted to turn this into a PHP class, I would wrap it in class myClass {}. I'm not sure how I would set the js to a property other than $output.= . I learned a ton from you. I'll definitely give you the green checkmark (not exactly a huge reward for your effort). Again, thank you so much for your solution and explanation. –  Laxmidi Sep 16 '11 at 18:32
    
Thanks, happy to help. I updated my answer with improvements to the notes and code. Now you can have multiple maps on a page. You are correct, the defaults in the JS are redundant. I used those for testing and to ensure they were set, but you can probably safely remove them. –  goto10 Sep 17 '11 at 19:26
1  
@goto10 - fyi, there is a trick you can do to get multidimensional arrays using wp_localize_script, see this bit of code. –  Milo Sep 17 '11 at 19:57
    
@Milo - Cool! Thanks for that. –  goto10 Sep 17 '11 at 21:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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