You can take advantage of html5 data-* attributes.
In your shortcode function, output a class name and the data attributes you'll need:
function my_plugin_shortcode( $shortcode_settings ) {
$elem_id = 'elem-id';
$settings_id = 'my-plugin-settings-id';
$output = '<div class="my-plugin-class" id="#'.$elem_id.'" data-settings-id="'.$settings_id.'"></div>';
return $output;
}
Then create a script named init.js and use wp_enqueue_script. Inside it put:
jQuery(document).ready(function($){
$('.my-plugin-class').each(function(){ // Loop thru each shortcode instance
var settings_id = $(this).data('settings-id'); // get data from attribute data-settings-id
$(this).plugin(settings_id); // initialize plugin and pass its settings
});
});
It will work even if you have multiple shortcodes in the same post or page.
Edit - Expanded answer to address the asker's requirements and questions:
(I cannot pre enqueue this piece of code because of some dynamic variables inside!)
You dont have to print the dynamic variables inside javascript file as it is printed out on the element itself using data-* attribute. init.js will then pull the settings from the data-* attributes and pass it to your jquery plugin.
where do I place this code in wordpress? I can create a javascript file, place it in wp_content in appropriate folder and call wp_enqueue_script with the path to that file. Is there a better way and how?
Ideally the init.js should be inside your plugin folder under the "js" directory. Eg. your-plugin/js/init.js
I dont want this piece of code running more than once (and thus initiating my plugin twice!)
It wont.
jQuery(document).ready
with dynamic variable name like so:$('#". $elem_id . "').plugin(".$settings_id.");